Why is this vector iterator not incrementable?

35,885

Solution 1

erase invalidates the iterator. You can't use it any more. Luckily for you, it returns an iterator that you can use:

vector <Base*>::iterator deleteIterator = m_basesVector.begin();
while (deleteIterator != m_basesVector.end()) {
    deleteIterator = m_basesVector.erase(deleteIterator);
}

Or:

m_basesVector.clear();

Are you responsible for freeing the memory referred to by the pointers in the vector? If that's the reason that you're iterating (and your real program has more code that you haven't shown, that frees those objects in the loop), then bear in mind that erasing from the beginning of a vector is a slow operation, because at each step, all the elements of the vector have to be shifted down one place. Better would be to loop over the vector freeing everything (then clear() the vector, although as Mike says that's not necessary if the vector is a member of an object that's being destroyed).

Solution 2

The problem is that you are trying to use an iterator while using the erase() function. erase(), push_back(), insert(), and other modifying functions invalidate iterators in STL.

Just use the clear() function:

City::~City()
{
    m_basesVector.clear();
}  

Solution 3

If you are trying to free the data in the vector, do this:

for (std::vector<Base*>::iterator it = v.begin(), e = b.end(); it != e; ++it) 
    delete *it;

Solution 4

Posting this just incase anyone else has this this problem and attempts this solution wondering why it's not working here's an actual solution/explanation.

@Steve Jessop - Your code is flawed and you've also got it written here... ( I've also edited his post to fix the issue as soon as it's approved it'll be fixed in the original post )

http://techsoftcomputing.com/faq/3779252.html

I don't see how this is a "Solution" to the issue when it create an new issue by making an endless loop there should be a deleteIterator++ within the while loop so that it actually reaches the end of the vector.

Also I've ran into this problem and my solution was inside the while loop checking whether the iterator was equal to the end or if the vector size was 0 and breaking before attempting to incrementing the iterator.

Ex.

    std::vector<RankPlayer*>::iterator Rank_IT = CurrentPlayers.begin();

    while ( Rank_IT != CurrentPlayers.end() ) 
    {    
        RankPlayer* SelPlayer = (*Rank_IT);

        if( strstr( SelPlayer->GamerTag, this->GamerTag ) != NULL )
        {

            delete[] SelPlayer->PlayerData;
            delete[] SelPlayer;
            Rank_IT = CurrentPlayers.erase( Rank_IT );
        }

        if( Rank_IT == CurrentPlayers.end() || CurrentPlayers.size() == 0 )
        {
            break;
        }
            ++Rank_IT;
    }

Solution 5

This is not relevant to the original problem posted above, but Google search on the error takes me to this page so I am posting it here for anyone to see.

I ran into this error message recently and all lines of codes checked out (there was no 'erase' or anything alike; the vector was merely read).

Eventually, I realized that there is a problem with nested loops.

For example, consider something like this:

`for (it=begin(); it!=end();i++)
{
    for (; it!=end();i++)
    {
    }
}`

When you are done with the nested loop, it will increment the iterator - and then, the parent loop will increment it again(!), ultimately making the iterator step over the end(). I.e. it would be "end()+1" if there were such a thing. Consequently, the parent loop throws this error at the next check.

To get around this, I ended up insert this line after the child loop:

`if (it == vStringList.end()) --it;`

Dirty, but works :D

I know it may be obvious to some, but I've been scratching my head over this for a while, lol

Share:
35,885
Roy Gavrielov
Author by

Roy Gavrielov

Updated on July 09, 2022

Comments

  • Roy Gavrielov
    Roy Gavrielov almost 2 years

    I'm trying to delete the vector's content and I'm getting an error - vector iterator is not incrementable, why is that?

    This is my destructor:

    City::~City()
    {
        vector <Base*>::iterator deleteIterator;
        for (deleteIterator = m_basesVector.begin() ; deleteIterator != m_basesVector.end() ; deleteIterator++)
            m_basesVector.erase(deleteIterator);
    }  
    

    thanks.

  • user2584401
    user2584401 over 13 years
    Well, whether they invalidate iterators depends on the container type.
  • riwalk
    riwalk over 13 years
    @Matt, it doesn't depend when using vectors.
  • Mike Seymour
    Mike Seymour over 13 years
    @Matt: erase will always invalidate iterators that refer to the erased element.
  • user2584401
    user2584401 over 13 years
    The other potential problem is that using clear() won't delete the pointers before removing them from the vector if that is necessary.
  • Bill
    Bill over 13 years
    @Matt: neither will erase().
  • Tim Post
    Tim Post over 12 years
    This is an answer and a rant, as well as a comment. I strongly suggest making it less of a rant and comment, or it will be quickly removed.