Назад к вопросам
Middle
93
questionbank

Что происходит с объектом vector при добавлении нового элемента?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

При добавлении нового элемента в std::vector:

  1. Проверка емкости: vector проверяет, достаточно ли текущей выделенной памяти (capacity()) для хранения нового элемента.
  2. Выделение нового буфера: Если текущая емкость недостаточна, vector выделяет новый, больший буфер памяти (как правило, в 1.5 или 2 раза больше текущего).
  3. Копирование/Перемещение элементов: Все существующие элементы копируются (или перемещаются, если доступно) из старого буфера в новый.
  4. Освобождение старого буфера: Старый буфер памяти освобождается.
  5. Добавление нового элемента: Новый элемент добавляется в конец нового буфера.
  6. Обновление счетчиков: Обновляются внутренние счетчики размера (size()) и емкости (capacity()) vector.

Если текущая емкость достаточна, новый элемент просто добавляется в конец существующего буфера, и обновляется только счетчик размера.

Пример:

#include <vector>
#include <iostream>

struct MyObject {
    int id;
    MyObject(int i) : id(i) { std::cout << "Construct " << id << std::endl; }
    MyObject(const MyObject& other) : id(other.id) { std::cout << "Copy Construct " << id << std::endl; }
    MyObject(MyObject&& other) : id(other.id) { std::cout << "Move Construct " << id << std::endl; other.id = -1;}
    ~MyObject() { std::cout << "Destruct " << id << std::endl; }
};

int main() {
    std::vector<MyObject> v; // Capacity is 0
    std::cout << "Adding 1:" << std::endl;
    v.push_back(MyObject(1)); // New buffer (size 1), construct 1, destruct temp
    std::cout << "Adding 2:" << std::endl;
    v.push_back(MyObject(2)); // Reallocation (capacity 2), move 1, construct 2, destruct 1, destruct temp
    std::cout << "Adding 3:" << std::endl;
    v.push_back(MyObject(3)); // Reallocation (capacity 4), move 1, move 2, construct 3, destruct 1, destruct 2, destruct temp
    std::cout << "Adding 4:" << std::endl;
    v.push_back(MyObject(4)); // No reallocation (capacity 4), construct 4, destruct temp

    // Program ends, vector destructed
    // Destruct 1, Destruct 2, Destruct 3, Destruct 4 (from final buffer)

    return 0;
}

Вывод может немного отличаться в зависимости от реализации STL, но общая логика с перевыделением и перемещением при нехватке емкости сохраняется.