2

I am having trouble in a multithreaded environment. I have a correctly "Multiple Read-Single Write"-Lock set up environment, that modifies a std::list. My problem now is, that i recieve an "list iterator not dereferencable"-exception and Visual is only displaying this if I inspect it:

data shows only (error) in visual debugger

The first item in the list has the value "0xcdcdcdcd".

What could be the cause? I would love to provide you more details, but I have no idea where to start, it already costed me several days of debugging into it, but if the code runs with breakpoints, this does not happen.

UPDATE

I have reduced it to now to a much more simple problem (sadly still not able to reduce it to a small non-working example). It is now run only in a single threaded environment - so no more multithreading issues can apply.

The list is filled with aroud 5000 elements, I make a call to data.resize(100) and it crashes - having removed ~3500 elements. Every element is always handled exactly the same, they all are contained in shared_ptr<>

I do not save any iterators, that may get invalid, it just crashes by having by having erased a random element in the list. I have no clue where to start.

EGOrecords
  • 1,959
  • 2
  • 19
  • 33
  • 2
    "but if the code runs with breakpoints, this does not happen." that suggests a race condition that invalidates your iterators – SingerOfTheFall Oct 13 '15 at 09:39
  • the underlaying container is a std::list, which does not really care about iterator invalidation upon insert/remove (except of course the removed elements) - but why does the debugger still display removed elements? – EGOrecords Oct 13 '15 at 09:41
  • http://en.wikipedia.org/wiki/Magic_number_(programming) suggests 0xCCCCCCCC : Used by Microsoft's C++ debugging runtime library to mark uninitialised stack memory –  Oct 13 '15 at 09:44
  • From that same link: 0xCDCDCDCD: "Used by Microsoft's C/C++ debug malloc() function to mark uninitialized heap memory, usually returned from HeapAlloc()" – Daniel Stevens Oct 14 '15 at 05:34

2 Answers2

2

Are you using a std::auto_ptr inside a container?

auto_ptr is deprecated in new versions of C++ and should only be used with caution.

auto_ptr does not copy well and so it should never be used insided containers.

Why it is wrong to use std::auto_ptr<> with standard containers

Use std::shared_ptr or another smart pointer instead (from boost for instance) if C++11 is not available.

Community
  • 1
  • 1
Nikko
  • 4,182
  • 1
  • 26
  • 44
  • thank you for pointing that out! I tried both, `std::unique_ptr` and `std::shared_ptr`. Both give the same result - "(error)" – EGOrecords Oct 13 '15 at 09:52
1

I have found an answer:

Common Causes that destroy STL-Cotainers is thread-Safety.

If you are modifying the container concurrently it might break, at random places and you will only see this breakage if you try to iterate over it. In my case there was a parallel "push_front" operation, that modified the container, and a typical data-race occurred. The typical feature to see such a behaviour, is when the list has a sensible size, but if you inspect it in the debugger it will display useful values only until a certain point, and from there only (error).

I managed to fix it by adding a write-lock around the push_front.

Another case I have seen this behaviour, was when i had a stack overflow and destroyed my std::list base. Depending on the amount of bytes that where overwritten, even the size might be in a sensible range, but the whole container (not like in the case stated above, where the first element was still a good one!) is corrupted.

I hope somebody doing the same coding, and misses a single lock-necessarity and tries to solve it as a stack issue will find this useful!

EGOrecords
  • 1,959
  • 2
  • 19
  • 33