Почему итератор до последнего элемента вектора содержит искаженное значение?(см. код) - PullRequest
0 голосов
/ 25 марта 2019

В приведенном ниже коде выдается сообщение об ошибке использования кучи после освобождения.

#include <iostream>

int main()
{
    unordered_map<int, vector<int>::iterator> mp;
    vector<int> num;

    auto insert = [&](int n)
    {
        if (mp.count(n) != 0)
            return false;

        num.push_back(n);
        mp[n] = prev(num.end());
        return true;    
    };

    insert(1);
    insert(2);
    insert(3);

    for (auto n : num)
        cout << n << endl;

    cout << endl;

    for (auto m : mp)
    {
        cout << m.first << " -> ";
        cout << distance(num.begin(), m.second) << endl; 
        // cout << *m.second << endl;
    }

    return 0;
}

Вывод приведенного выше кода:

1
2
3

3 -> 2
1 -> -16
2 -> -7

Очевидно, что происходит сбой при попытке доступа *m.second.Почему значения итератора кажутся здесь испорченными?

Я попытался заменить вектор списком, и приведенный выше код работает нормально.Интересно, это как-то связано с расширением вектора на "push_back"?Я пробовал другие способы получить итератор до последнего элемента вектора с безразличными результатами.

1 Ответ

0 голосов
/ 25 марта 2019

Итераторы и ссылки становятся недействительными в vector при вызове push_back, см. reference . Вектор реализован как один непрерывный блок памяти. Когда вы нажимаете на новые элементы и нет места для их хранения, выделяется новый блок памяти и добавляется новый элемент. Таким образом, итераторы (указатели) на старые элементы могут быть признаны недействительными.

Ваш код работает на std::list, потому что список реализован с использованием узлов . Один узел указывает на другой, и при добавлении новых данных в список расположение узлов не изменяется, поэтому итераторы действительны.

Ваш код с vector будет работать, но вам нужно оценить, сколько элементов можно хранить в векторе, после того как вектор был создан, вызовите его reserve(N) - он готовит вектор для хранения N элементов без аннулирования итераторов когда push_back вызывается.

...