Недействительность итератора в циклах while и vs for - PullRequest
1 голос
/ 07 марта 2020

Как обрабатывается аннулирование итераторов в цикле while и for?

Например, этот код не работает, поскольку итераторы становятся недействительными после вставки:

    vector <int> v = {1,5,5,5,5,2,3,4,5,6,7};
    vector<int> :: iterator iter = v.begin();
    vector <int> :: iterator mid = v.begin() + (v.end()-v.begin())/2;

    while(iter != mid){
        if(*iter == 5){
            iter = v.insert(iter, 0);
            iter++;
        }
        iter++;
    }

Однако, если я заменяю while l oop с этим для l oop компилируется и работает правильно:

   for(auto curr = iter; curr != mid; ++curr){
        if(*iter == 5){
            iter = v.insert(iter, 0);
            iter++;
        }
        iter++;
    }

Почему for l oop работает, а l oop не работает?

1 Ответ

1 голос
/ 07 марта 2020

Оба цикла неверны, потому что после вставки элемента в вектор итератор mid становится недействительным. Память, выделенная для элементов вектора, может быть перераспределена.

Чтобы добиться того, что вы пытаетесь сделать, лучше ввести количество итераций, например,

auto n = v.size() / 2;

for ( auto iter = v.begin(); n != 0; n-- )
{
    if( *iter == 5 )
    {
        iter = v.insert(iter, 0);
        iter++;
    }
    iter++;
}

Вот демонстрационная программа.

#include <iostream>
#include <vector>

int main() 
{
    std::vector <int> v = { 1, 5, 5, 5, 5, 2, 3, 4, 5, 6, 7 };

    for ( const auto &item : v ) std::cout << item << ' ';
    std::cout << '\n';

    auto n = v.size() / 2;

    for ( auto it = v.begin(); n != 0; n-- )
    {
        if ( *it == 5 )
        {
            it = v.insert( it, 0 );
            ++it;
        }

        ++it;
    }

    for ( const auto &item : v ) std::cout << item << ' ';
    std::cout << '\n';

    return 0;
}

Вывод программы:

1 5 5 5 5 2 3 4 5 6 7 
1 0 5 0 5 0 5 0 5 2 3 4 5 6 7

Или l oop может выглядеть как

for ( auto it = v.begin(); n--; ++it )
{
    if ( *it == 5 )
    {
        it = v.insert( it, 0 );
        ++it;
    }
}
...