Какие проблемы есть у std::vector?

«Какие проблемы есть у std::vector?» — вопрос из категории STL, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основные проблемы std::vector в C++:

  1. Инвалидация итераторов и ссылок при переаллокации. Любая операция, увеличивающая размер (push_back, emplace_back, resize), может вызвать переаллокацию, если size() превышает capacity(). Это делает недействительными все итераторы, указатели и ссылки на элементы вектора.

    std::vector<int> vec = {1, 2, 3};
    int* p = &vec[0];
    int& ref = vec[1];
    vec.push_back(4); // Может вызвать переаллокацию
    // *p и ref теперь могут ссылаться на невалидную память (UB)

    Решение: Используйте reserve() для предварительного выделения памяти, если известен примерный размер.

  2. Высокая стоимость вставки/удаления в середину. Операции insert() и erase() имеют сложность O(n), так как требуют сдвига всех последующих элементов.

  3. Потребление памяти. Метод reserve() увеличивает capacity, но не уменьшает его. Вектор может долго хранить неиспользуемую память. Чтобы её освободить, используется идиома "swap-trick": std::vector<T>(v).swap(v) или, начиная с C++11, shrink_to_fit() (не гарантирует уменьшения).

  4. Отсутствие потокобезопасности. Одновременная модификация вектора из разных потоков без внешней синхронизации приводит к неопределённому поведению (UB).

  5. Исключительная безопасность. Некоторые операции (например, emplace_back) предоставляют строгую гарантию исключений (strong exception safety) только при условии, что конструктор перемещения или копирования элемента не выбрасывает исключений. В противном случае вектор может остаться в допустимом, но неопределённом состоянии.