-
Vector Iterator Help
Hi,
Im trying to remove an element from a vector inside a loop using an iterator, which it seems I am doing incorrectly.
Code:
for(vector<bomb>::iterator bm = bombs.begin(); bm!=bombs.end(); ++bm)
{
....
bombs.erase(bm);
}
Looking around it seems this fails (it gives a segmentation fault) because i am using an invalidated iterator, but im not sure how to correct this?
Thanks for any help.
Jack
-
A vector's iterators are invalidated when its memory is reallocated. Additionally, inserting or deleting an element in the middle of a vector invalidates all iterators that point to elements following the insertion or deletion point.
So use a container which is more friendly in this situation or stop accessing any invalidated iterator, particularly bm. showing the code of the whole loop would be helpful to answer your question in depth.
for example, if you want to delete a number of bombs with a special property in a single loop, this could help:
Code:
if(...)
{
vector<bomb>::iterator pre = bm;
bombs.erase(bm);
bm = pre;
}
-
erase returns an iterator that you should use to continue through the vector. A typical format for erasing while iterating looks like this:
Code:
for(vector<bomb>::iterator bm = bombs.begin(); bm!=bombs.end(); )
{
if (/* erase */)
bm = bombs.erase(bm);
else
++bm;
}
-
Thanks, the entire code below, i would like to stick with the vector container if at all possible, i have modified my loop/erase code to 'attempt' to re validate the iterator, but it still doesnt work.
Code:
for(vector<bomb>::iterator bm = bombs.begin(); bm!=bombs.end(); )
{
// Draw bomb
glRectd(bm->x1, bm->y1, bm->x2, bm->y2);
// Move bomb downards
bm->y1-= delta_time * BOMB_VELOCITY;
bm->y2-= delta_time * BOMB_VELOCITY;
// Check for impact
if((bm->x2 <= ship->RightX && bm->x1 >= ship->LeftX) && (bm->y2 <= ship->TopY && bm->y2 >= ship->LeftY))
{
// Impact occured
bm = bombs.erase(bm); // destroy bomb
ship->ship_destroy = true;
ship->lives--;
}
++bm;
}
This still segment faults :S
Thanks again
-
You didn't quite follow my example. Notice that in my example, ++bm is called in the else. That means it isn't called if erase is called. In your code ++bm will always be called every time through the loop, which is why it fails.
You should only do one or the other. Either call erase and save the return value, or increment with ++.
-
That seems to have fixed the problem, thanks very much for the help, much appreciated.