Why is this vector iterator not incrementable?

前端 未结 8 1191
没有蜡笔的小新
没有蜡笔的小新 2020-12-13 10:41

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:

C         


        
相关标签:
8条回答
  • 2020-12-13 10:46

    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;
    
    0 讨论(0)
  • 2020-12-13 10:48

    Any iterator pointing to the deleted element or to the elements after the one that is deleted gets invalidated when the vector's erase method is called. Erase method returns a valid iterator pointing to the next element in the vector. You should use that iterator to continue your looping & not increment the invalidated iterator. You may also use the clear method to remove all the elements in the vector. However, you will need to remember to explicitly de-allocate any allocated memory for the elements.

    0 讨论(0)
  • 2020-12-13 10:49

    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();
    }  
    
    0 讨论(0)
  • 2020-12-13 10:53

    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).

    0 讨论(0)
  • 2020-12-13 10:58

    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;
        }
    
    0 讨论(0)
  • 2020-12-13 11:06

    This code leaks all the contents of the vector - you have to delete *deleteIterator in the loop too. You can avoid all of this by using Base instead of Base* as the vector contents, then clear() will destruct them for you. Or use boost::ptr_vector which automates destruction if you do need raw pointers.

    Calling erase() in a forward iteration like this can be very costly if the vector is large, as every element above the current position has to be moved down to ensure elements remain contiguous. Avoid manual erase of the type you propose, for this and other reasons.

    0 讨论(0)
提交回复
热议问题