Iterators

Hey everybody, I have 2 vectors - openList and closedList - Im trying to check if a item on the openList is on the closedList and if it is i need to delete it.

My current code is
1
2
3
4
5
6
7
8
for (it=closedList.begin(); it!=closedList.end(); ++it) { //Checking to see if any tiles on openList are on closedList
    for (it2=openList.begin(); it2!=openList.end(); ++it2) {
        if (it->x == it2->x && it->y == it2->y) { //<- Crashes right here
            it2 = openList.erase(it2);
            debugmsg(it2->x, it2->y, "Erased tile from openlist");
        }
    }
}

For some reason it2 becomes invalid for no reason(I think thats the correct term? It doesnt has any info in it) but my vectors are always filled with correct data.
It runs perfectly fine for the first few passes but then just crashes with the signal EXC_BAD_ACCESS
Please help! D:
This is probably crashing when you remove the last element in openList.

This is what's happening:

1) it2 = openList.erase( <lastElement> );. erase returns an iterator that is one past the removed element. So if you just removed the last element, it2 now == openList.end()

2) the for loop then increments it2. it2 becomes invalid.

3) it2 is invalid and no longer == openList.end, so the for loop does not exit.

4) loop body attempts to dereference it2, resulting in a crash (if not the first time, then one of the many, many, many times the loop will continue)



As a general rule... if you are removing elements from a container... you do not want to use a for loop (for this very reason). You want to use a while loop:

1
2
3
4
5
6
7
8
9
10
11
for(it = closedList.begin(); it != closeList.end(); ++it)
{
  it2 = openList.begin();
  while( it2 != openList.end() )
  {
    if( ... want to remove element... )
      it2 = openList.erase(it2);
    else
      ++it2;
  }
}
Last edited on
1
2
3
4
5
6
7
8
9
for (it=closedList.begin(); it!=closedList.end(); ++it) { 
    for (it2=openList.begin(); it2!=openList.end(); /* ++it2 *** removed */ ) {
        if (it->x == it2->x && it->y == it2->y) { 
            debugmsg(it2->x, it2->y, "Erased tile from openlist");
            it2 = openList.erase(it2); // *** changed the order 
        }
        else ++it2 ; // *** added
    }
}


EDIT: Already answered by Dish; but leaving it in because debugmsg() should be before the erase()
Last edited on
Wow!! Thanks alot :D
JLBorges's comment about erasing after the debugmsg is also important. Be sure you do that as well. I didn't catch that one.
Topic archived. No new replies allowed.