vector erase problem

Started by
4 comments, last by destiny_breaker86 18 years, 8 months ago
I'm new to vectors so this might seem like a stupid question but I just can't figure it out. This code is just a test for something else actually. As I'm looping through a vector I will want it to erase a certain item if some certain condition is true. It seems to work in this code at least unless the item to be erased is the last item in the vector. It will let me erase any of the other items except the last one (like if I tested *iter == 20 instead of *iter == 40 it would work) Heres my code:

vector<int> intVec;
vector<int>::iterator iter;

intVec.push_back(10);
intVec.push_back(20);
intVec.push_back(30);
intVec.push_back(40);

for(iter = intVec.begin(); iter != intVec.end(); iter++)
{
    if(*iter == 40)
        intVec.erase(iter);
}



Any help would be great!
Advertisement
vector::erase() invalidates iterators into the vector at or after the point of erasure. For this reason vector::erase() returns an iterator to the element that was after the erased element(s). So you can rewrite your loop like:

for(iter = intVec.begin(); iter != intVec.end();){    if(*iter == 40)        iter = intVec.erase(iter);    else        ++iter;}


However, it's generally less error prone to use std::remove_if() to remove the elements then call vector::erase().
SiCrane is half right, but the problem is that erasing an element from a vector MAY invalidate any iterators to that vector.

The best think you can do is break out of the loop after erasing, assuming there's only a single item you want to erase.

The second-best is to use something from <algorithm>, such as std::copy_if.

The third-best is to re-construct the iterator using indexing after erasing.

Also, if you want to "find and erase" elements in the vector a lot, you probably want some other data structure that's better at finding elements. std::set<> comes to mind.
enum Bool { True, False, FileNotFound };
Quote:Original post by hplus0603
SiCrane is half right, but the problem is that erasing an element from a vector MAY invalidate any iterators to that vector.

No, the standard is quite clear, std::vector::erase() "Invalidates all the iterators and references after the point of erasure." (Section 24.2.4.3 paragraph 3) There's no may involved, those suckers are invalidated, and that's the reason why vector::erase() returns an iterator.
You can also use (I do it like this)

for (int loop=0; loop < intVet.size(); loop++){   if (intVec[loop]==40)    {     intVec.erase(intVec.begin() + loop)     loop--    }}


This way you can wipe out a whole vector 1 by 1 all the way to 0!

But unforunetly, the vector structure it's self still resides in memory, it's not too big, but a vector will NEVER FULLY release all of it's memory until it goes out of scope.

but theres a trick someone showed me how to clear out a vector, while still in scope.

vector<int>().swap(intVec);

basicly you would call this in another scope (a function)

what happens, is it fully moves the entire vector into your vector<int>
which is a temporary vector.

But once you leave the function, you just went out of scope, so that temp vector gets killed, fully.



Black Sky A Star Control 2/Elite like game
Hey thanks to everyone, that really cleared it up for me.

This topic is closed to new replies.

Advertisement