Working with STL-Vector
-
I wrote this :
while (!(m\_WorkerThreadList.empty())) { for ( it = m\_WorkerThreadList.begin(); it != m\_WorkerThreadList.end(); it++) if (!((\*it)->isAlive())) { delete (\*it); it = m\_WorkerThreadList.erase(it); } }
I found, that not all elements are actually deleted. The programm did not crash though, unless i used the debugger. If i just let the Debug build run, things where fine, except for a memory leak. If i used a debugger, the programm chrashed due to memory violation. However, that's not the problem here. It's a classic for loop thing.
This is supposed to be about subtle bugs!
Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
-
Chris Meech wrote:
How can a 'dead' object respond to the function call isAlive()
It's really simple you know - just include
voodoo.h
and derive from classLivingDead
. But before you run the application be shure to put a circle of chalk around your PC and Monitor.LOL. :-D You know I have some apps that have included
voodoo.h
. It seems they behave very strangely at times. Wonder why?. :cool:Chris Meech I am Canadian. [heard in a local bar] Nobody likes jerks. [espeir] Hey, I am part of a special bread, we are called smart people [Captain See Sharp] The zen of the soapbox is hard to attain...[Jörgen Sigvardsson] I wish I could remember what it was like to only have a short term memory.[David Kentley]
-
Yes, removing items from a container whilst iterating through it is probably a bad idea! :) If necessary, I tend to add the elements I want to keep to a second vector, and then overwrite the original with the second. Depends on the vector contents though - being the STL, there are no doubt a number of ways you can do this!
Kicking squealing Gucci little piggy.
Rob Caldecott wrote:
Yes, removing items from a container whilst iterating through it is probably a bad idea!
Not at all! Just remember where the iterations should continue: vector<>.erase() gives the next iterator.
-- The Blog: Bits and Pieces
-
Rob Caldecott wrote:
Yes, removing items from a container whilst iterating through it is probably a bad idea!
Not at all! Just remember where the iterations should continue: vector<>.erase() gives the next iterator.
-- The Blog: Bits and Pieces
Oops! Of course it does! I totally forgot. However, I still prefer to use
std::remove
orstd::remove_if
over hand-crafted loops, to avoid potential issues like this. In the case of the code sample shown, I would also be using avector
of smart pointers, rendering thedelete
call redundant. I prefer to use algorithms orstd::for_each
wherever possible.
Kicking squealing Gucci little piggy.
The Rob Blog -
I wrote this :
while (!(m\_WorkerThreadList.empty())) { for ( it = m\_WorkerThreadList.begin(); it != m\_WorkerThreadList.end(); it++) if (!((\*it)->isAlive())) { delete (\*it); it = m\_WorkerThreadList.erase(it); } }
I found, that not all elements are actually deleted. The programm did not crash though, unless i used the debugger. If i just let the Debug build run, things where fine, except for a memory leak. If i used a debugger, the programm chrashed due to memory violation. However, that's not the problem here. It's a classic for loop thing.
The reason is simple. The
it++
in the for loop should not be present if theit = m_WorkerThreadList.erase(it);
line is executed as if you do both you've skipped two elements not one!Steve
-
LOL. :-D You know I have some apps that have included
voodoo.h
. It seems they behave very strangely at times. Wonder why?. :cool:Chris Meech I am Canadian. [heard in a local bar] Nobody likes jerks. [espeir] Hey, I am part of a special bread, we are called smart people [Captain See Sharp] The zen of the soapbox is hard to attain...[Jörgen Sigvardsson] I wish I could remember what it was like to only have a short term memory.[David Kentley]
Have you by any chance worked for 3dfx? ;)
-- No humans were probed in the making of this episode
-
This is supposed to be about subtle bugs!
Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
It's subtle for beginners of STL who aren't quite familiar with iterators, while for those who are, it's one of those "got burned once, and learned from it"-bugs.
-- Secreted by the Comedy Bee
-
It's subtle for beginners of STL who aren't quite familiar with iterators, while for those who are, it's one of those "got burned once, and learned from it"-bugs.
-- Secreted by the Comedy Bee
Yes. I apologise - I was in grumpy-old-git mode when I wrote my comment. It only happens because I am a grumpy old git, but some days I'm better at hiding the fact. :(
Phil
The opinions expressed in this post are not necessarily those of the author, especially if you find them impolite, inaccurate or inflammatory.
-
The reason is simple. The
it++
in the for loop should not be present if theit = m_WorkerThreadList.erase(it);
line is executed as if you do both you've skipped two elements not one!Steve
-
I wrote this :
while (!(m\_WorkerThreadList.empty())) { for ( it = m\_WorkerThreadList.begin(); it != m\_WorkerThreadList.end(); it++) if (!((\*it)->isAlive())) { delete (\*it); it = m\_WorkerThreadList.erase(it); } }
I found, that not all elements are actually deleted. The programm did not crash though, unless i used the debugger. If i just let the Debug build run, things where fine, except for a memory leak. If i used a debugger, the programm chrashed due to memory violation. However, that's not the problem here. It's a classic for loop thing.