2

Ok, I've run into this issue multiple times and thought it would be nice to throw this out to the good people on SO.

Say I have made a class, lets call it Resource. So the Resource class has a boolean variable which indicates weather any instance is active or not.

Now, I create a container which holds references to objects of the Resource type.

Over time , some of them get deactivated and I want to delete these deactivated objects so that they free up memory. Invariably I try to do this by : trying to iterate over the elements in the container and deleting the ones flagged as inactive. This , obviously leads to problems with iterator invalidation and the program starts throwing runtime errors.

So finally, my question is , what is the best method to safely delete objects depending on some condition that can only be evaluated by looking into the contents of the object.

angryInsomniac
  • 829
  • 2
  • 13
  • 27
  • 1
    possible duplicate of [deleting while iterating](http://stackoverflow.com/questions/3901356/deleting-while-iterating) – Péter Török Mar 12 '12 at 11:53
  • possible duplicate of [iterate vector, remove certain items as I go](http://stackoverflow.com/questions/1604588/iterate-vector-remove-certain-items-as-i-go) – Bo Persson Mar 12 '12 at 12:26
  • Not talking about just vectors or lists, also maps and other associative containers. – angryInsomniac Mar 13 '12 at 06:27

2 Answers2

4

Use the erase-remove idiom with std::remove_if. E.g.:

std::vector<int> myvec;
...
myvec.erase(std::remove_if(myvec.begin(),myvec.end(), [] (int i) -> bool { return false; }), myvec.end());
KillianDS
  • 16,936
  • 4
  • 61
  • 70
  • What about associative containers like maps ? std::remove_if doesnt work for them I gather. – angryInsomniac Mar 13 '12 at 06:25
  • @angryInsomniac: no it doesn't work because it would break ordering. [This question](http://stackoverflow.com/questions/9515357/map-lambda-remove-if) provides an answer for that problem. – KillianDS Mar 13 '12 at 07:30
0

The safest method is to use std::remove_if. This will move all items that match the given predicate to the end of the sequence. You can then delete them.

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • What about associative containers like maps ? – angryInsomniac Mar 13 '12 at 06:24
  • With a map you can delete the element an iterator points to without invalidating any other iterators. That means you can do `your_map.erase(it++);`. See [this question](http://stackoverflow.com/questions/6438086/) for more information. – Björn Pollex Mar 13 '12 at 07:28