← Назад ко всем вопросам

Что происходит при добавлении в vector элемента сверх изначального capacity

1️⃣ Как кратко ответить

При добавлении элемента в std::vector сверх его текущей емкости (capacity), происходит перераспределение памяти: выделяется новый блок памяти, обычно в 2 раза больше текущего, все элементы копируются в новый блок, и старый блок освобождается.

2️⃣ Подробное объяснение темы

std::vector — это динамический массив, который управляет памятью автоматически. Он имеет два важных свойства: размер (size) и емкость (capacity). size — это количество элементов, которые в данный момент содержатся в векторе, а capacity — это количество элементов, которые вектор может вместить без необходимости выделения новой памяти.

Когда вы добавляете элемент в std::vector и его текущая емкость недостаточна для размещения нового элемента, происходит следующее:

  1. Выделение новой памяти: Вектор выделяет новый блок памяти, который обычно в два раза больше текущей емкости. Это делается для того, чтобы минимизировать количество операций по выделению памяти, которые являются дорогостоящими.

  2. Копирование элементов: Все существующие элементы копируются из старого блока памяти в новый. Это может быть дорогостоящей операцией, особенно если вектор содержит много элементов или если элементы имеют сложные конструкторы копирования.

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

  4. Обновление метаданных: Обновляется значение capacity вектора, чтобы отражать новую емкость.

Пример кода, демонстрирующий это поведение:

#include <iostream>
#include <vector>
​
int main() {
    std::vector<int> vec;
    vec.reserve(2); // Устанавливаем начальную емкость вектора равной 2
    std::cout << "Initial capacity: " << vec.capacity() << std::endl;
​
    vec.push_back(1); // Добавляем первый элемент
    vec.push_back(2); // Добавляем второй элемент
    std::cout << "Capacity after adding two elements: " << vec.capacity() << std::endl;
​
    vec.push_back(3); // Добавляем третий элемент, что превышает текущую емкость
    std::cout << "Capacity after adding third element: " << vec.capacity() << std::endl;
​
    return 0;
}
  • std::vector<int> vec; — создаем пустой вектор vec типа int.
  • vec.reserve(2); — резервируем память для 2 элементов, устанавливая начальную емкость вектора.
  • vec.push_back(1); и vec.push_back(2); — добавляем два элемента, которые помещаются в зарезервированную память.
  • vec.push_back(3); — добавляем третий элемент, что превышает текущую емкость, вызывая перераспределение памяти.
  • std::cout используется для вывода текущей емкости вектора до и после добавления элементов.

Этот процесс перераспределения памяти делает std::vector эффективным для большинства сценариев использования, но также может привести к временным затратам, если перераспределение происходит часто. Поэтому, если вы заранее знаете, сколько элементов будет в векторе, рекомендуется использовать метод reserve, чтобы избежать частых перераспределений.

Тема: STL: Контейнеры
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки