Поведение сохранённого итератора после изменения контейнера

Для list сохранённый итератор остаётся действительным и указывает на 0. Для vector перераспределение памяти при росте инвалидирует его; последующее разыменование даёт неопределённое поведение.

Короткий ответ

Что ответить на собеседовании

Для list сохранённый итератор остаётся действительным и указывает на 0. Для vector перераспределение памяти при росте инвалидирует его; последующее разыменование даёт неопределённое поведение.

Подробный разбор

Ответ с пояснениями

Условие

Исследовать, как ведёт себя итератор, полученный до модификации контейнера, при последующем использовании с разными STL‑контейнерами (например, std::list и std::vector).


template<typename C>
void process(C& container) {
    container.push_back(0);
    auto it = container.begin();
    for (size_t i = 1u; i < 1000u; ++i) {
        container.push_back(i);
    }
    std::cout << "First: " << *it << std::endl;
}

int main(int argc, char** argv) {
    std::list<int> lst;
    process(lst);
    std::vector<int> vec;
    process(vec);

    return EXIT_SUCCESS;
}

Ответ

Для list сохранённый итератор остаётся действительным и указывает на 0. Для vector перераспределение памяти при росте инвалидирует его; последующее разыменование даёт неопределённое поведение.

Нельзя обещать для vector конкретное число, «мусор» или обязательное падение. Проблема появляется при первой реаллокации после сохранения it; обычный рост исходно пустого vector её вызывает.

Для этого примера можно заранее вызвать vec.reserve(1000) до process(vec), чтобы вставки укладывались в ёмкость. Другой вариант — получать итератор после заполнения. Стабильность итераторов list не означает, что он всегда быстрее vector.

Источник: eel.is.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее