Archived

This topic is now archived and is closed to further replies.

std::vector<T>::erase()

This topic is 5130 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Just a quick question this time, since the erase() method invalidates the iterator passed, is the following safe?
std::vector<int> vlist;
std::vector<int>::iterator itr;

// Add int elements here


// remove every element == 0

for(itr = vlist.begin(); itr != vlist.end(); itr++)
   if((*itr) == 0){
      itr--;
      vlist.erase(itr + 1);
   }

edit: removed some junk so to lessen the confusion [edited by - wavarian on November 27, 2003 10:32:32 PM]

Share this post


Link to post
Share on other sites
For vector<> that's not OK; all iterators are invalidated. For list<> you only invalidate the item pointed at.

However, most people use the semantic of the post-increment to do the same thing.


std::list<> the_list;
while( iter != the_list.end() ) {
if( SHOULD_DELETE( *iter ) ) {
the_list.erase( iter++ );
}
else {
++iter;
}
}


The problem with your approach is that it fails when you want to delete the first item (as you try to -- on begin()).

[edited by - hplus0603 on November 27, 2003 11:24:55 PM]

Share this post


Link to post
Share on other sites
vector::erase() returns an iterator pointing to the value just passed the value erased, so instead of doing the iterator increment/decrement dance, try something like:

for(itr = vlist.begin(); itr != vlist.end(); ) {
if((*itr) == 0){
itr = vlist.erase(itr); // effectively increments the iterator
} else {
itr++;
}
}


However, worrying about invalidated iterators is generally bad news. Consider using std::remove() or std::remove_if() instead. i.e.:

vlist.erase(std::remove(vlist.begin(),
vlist.end(),
0),
vlist.end());

Fewer worries about invalidated iterators, and more efficient to boot.

edit: !@#$! smilies

[edited by - SiCrane on November 27, 2003 11:04:47 PM]

Share this post


Link to post
Share on other sites
Interesting points, I had tried using the return value of erase() within the loop, but for some strange reason I got a runtime error.

I''ll have to look into it again. And yeah my method is clearly not safe as someone had pointed out with my backtracking method.

And I think your method of using std::remove() looks pretty sweet SiCrane, just might do the trick

Cheers again guys, I''m just one step closer to understanding how to properly use STL.

Share this post


Link to post
Share on other sites