Question on vector iterators

Hi, I'm having an issue trying to get the code below to work and I have a feeling it's down to my misunderstanding of iterators and vectors.

I have a vector of Shape pointers. Shapes move around the screen and need to be destroyed when two come into contact with each other. I can delete the Shapes referenced by each pointer no problem but when I come to remove the Shape pointer from the vector, or do anything with the iterator, it crashes.

I have tried to comment an example and my thought process in the code below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
  //...
  
  vector<Shape*>* entities = lvl.getEntities(); //e.g {shape1, shape2, shape3, shape4}
  vector<Shape*>::iterator it1;
  vector<Shape*>::iterator it2;

  Shape* s1;
  Shape* s2;

  while (true) {
      // shape movement code
  

      for (it1 = entities->begin(); it1 != entities->end(); it1++) {
          s1 = *it1;
          for (it2 = it1 + 1; it2 != entities->end(); it2++) {
              s2 = *it2;
              if (s1->collidesWith(s2)) {
                  // e.g. shape1 collides with shape3

                  // destroy
                  delete *it1;
                  delete *it2;
                  
                  entities->erase(it1); //now {shape2, shape3, shape4}

                  // Now it2 points to shape4 instead of shape3. So decrement.

                  it2--; // CRASH: vector iterator not decrementable
                  // even if I remove the previous line and try to erase it2 without decrementing:
                  entities->erase(it2); // CRASH: vector erase iterator outside range
                  it1--;

                  break;
                  }
              }
          }

          if (entities->size() <= 1) break;
      }
      return 0;
}


It is my understanding that it2 should point to shape4 after removing shape1 in the example. Why is it2 breaking after removing an element from the vector? Is two simultaneous vectors a bad idea?

Any help would be greatly appreciated!
Last edited on
http://www.cplusplus.com/reference/vector/vector/erase/
Iterator validity
Iterators, pointers and references pointing to position (or first) and beyond are invalidated, with all iterators, pointers and references to elements before position (or first) are guaranteed to keep referring to the same elements they were referring to before the call.


Return value
An iterator pointing to the new location of the element that followed the last element erased by the function call.
1
2
entities->erase(it2); //it2>it1, so it1 would not become invalidated
it1 = entities->erase(it1); //keep it1 valid 
however if you erase `it1', then the outer loop should not increment it. I don't think that doing `it1--' is correct, ¿what if it is pointing to begin()? then it would become invalid.

Also, ¿can't a shape collide against another two at the same time?


Check out http://www.cplusplus.com/reference/algorithm/remove_if/
Last edited on
Topic archived. No new replies allowed.