Подтвердить что ты не робот

Почему этот векторный итератор не увеличивается?

Я пытаюсь удалить векторный контент, и я получаю ошибку. Итератор вектора не увеличивается, почему?

Это мой деструктор:

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

спасибо.

4b9b3361

Ответ 1

erase аннулирует итератор. Вы больше не можете его использовать. К счастью для вас, он возвращает итератор, который вы можете использовать:

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

Или:

m_basesVector.clear();

Вы отвечаете за освобождение памяти, на которую ссылаются указатели в векторе? Если это причина, по которой вы повторяете (и ваша реальная программа имеет больше кода, который вы не показывали, что освобождает эти объекты в цикле), то имейте в виду, что стирание с начала вектора является медленной операцией, потому что на каждом шаге все элементы вектора должны быть сдвинуты вниз на одно место. Лучше было бы перебрать вектор, освобождающий все (тогда clear() вектор, хотя, по словам Майка, не обязательно, если вектор является членом уничтожаемого объекта).

Ответ 2

Проблема заключается в том, что вы пытаетесь использовать итератор при использовании функции erase(). erase(), push_back(), insert() и другие изменяющие функции делают недействительными итераторы в STL.

Просто используйте функцию clear():

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

Ответ 3

Если вы пытаетесь освободить данные в векторе, сделайте следующее:

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

Ответ 4

Проводя это просто, если у кого-то еще есть эта проблема, и пытается это решение задаться вопросом, почему он не работает здесь, фактическое решение/объяснение.

@Steve Jessop - Ваш код испорчен, и вы также получили его здесь... (Я также отредактировал его сообщение, чтобы исправить проблему, как только она утвердится, будет исправлена ​​в исходном сообщении)

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

Я не вижу, как это "решение" проблемы, когда она создает новую проблему, создавая бесконечный цикл, в цикле while должен быть deleteIterator ++, чтобы он фактически доходил до конца вектора.

Также я столкнулся с этой проблемой, и мое решение находилось внутри цикла while, проверяя, был ли итератор равным концу или если размер вектора был равен 0 и разбился, прежде чем пытаться увеличить итератор.

Исх.

    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;
    }

Ответ 5

Любой итератор, указывающий на удаленный элемент или на элементы после удаляемого, становится недействительным при вызове метода стирания вектора. Метод Erase возвращает действительный итератор, указывающий на следующий элемент в векторе. Вы должны использовать этот итератор для продолжения цикла и не увеличивать недействительный итератор. Вы также можете использовать метод clear для удаления всех элементов в векторе. Тем не менее, вам нужно будет помнить, что явным образом выделяю любую выделенную память для элементов.

Ответ 6

Этот код просачивает все содержимое вектора - вы также должны delete *deleteIterator в цикле. Вы можете избежать всего этого, используя Base вместо Base* в качестве содержимого vector, а затем clear() уничтожит их для вас. Или используйте boost::ptr_vector, который автоматизирует уничтожение, если вам нужны исходные указатели.

Вызов erase() в передовой итерации, такой как это может быть очень дорогостоящим, если vector велико, так как каждый элемент выше текущей позиции должен быть перемещен вниз, чтобы гарантировать, что элементы остаются смежными. Избегайте ручного удаления типа, который вы предлагаете, по этой и другим причинам.

Ответ 7

Итераторы векторов являются инкрементальными, но если вы удаляете элементы, содержимое вектора изменяется и, следовательно, итератор недействителен.

Итак, если вы удаляете объекты, вы должны использовать возвращаемое значение erase(), которое дает вам следующий действительный итератор.

Ответ 8

Это не относится к исходной проблеме, описанной выше, но поиск Google по ошибке приводит меня к этой странице, поэтому я размещаю ее здесь для всех, кто ее видит.

В последнее время я столкнулся с этим сообщением об ошибке, и все строки кода были проверены (не было ни "стирания", ни чего-либо подобного, вектор был просто прочитан).

В конце концов, я понял, что существует проблема с вложенными циклами.

Например, рассмотрим что-то вроде этого:

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

Когда вы закончите с вложенным циклом, он увеличит итератор - и затем родительский цикл снова увеличит его (!), в результате сделав шаг итератора по окончании(). То есть это было бы "end() + 1", если бы было такое. Следовательно, родительский цикл выдает эту ошибку при следующей проверке.

Чтобы обойти это, я вставил эту строку после цикла child:

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

Грязный, но работает: D

Я знаю, что это может быть очевидно для некоторых, но я некоторое время царапаю голову над этим, lol