TGViewer
C++ geek C++ geek @cpp_geek · 3.53K subscribers
Post #399 1.67K
🏗 Анатомия std::vector::push_back: Когда память заканчивается

Мы все любим push_back. Это удобно: просто кидаешь данные в вектор, а он сам разбирается с памятью. Но что происходит, когда вы добавляете элемент, а место (capacity) закончилось?

Происходит Реаллокация (Reallocation). И это дорогая операция.

⚙️ Что происходит «под капотом»?

1. Поиск новой земли: Вектор понимает, что текущий буфер полон. Он просит у операционной системы выделить новый блок памяти. Обычно он в 1.5 или 2 раза больше предыдущего (геометрический рост).

2. Великое переселение: Все элементы из старого блока копируются (или перемещаются, если есть noexcept move-конструктор) в новый блок.
⚫️Представьте, что вы перевозите 10,000 коробок в новый дом только ради того, чтобы поставить еще одну.

3. Зачистка: Для всех объектов в старом блоке вызываются деструкторы.

4. Снос: Старая память возвращается системе.

🚨 Почему это проблема?

1. Удар по производительности:
Обычно push_back работает за амортизированное O(1) (мгновенно). Но в момент реаллокации сложность подскакивает до O(N). Это вызывает непредсказуемые лаги (latency spikes).

2. Инвалидация итераторов и ссылок (ОПАСНО):
Это источник багов №1. После реаллокации старая память удалена. Все указатели, ссылки и итераторы, которые смотрели на элементы вектора, становятся недействительными.


std::vector<int> vec = {1, 2, 3};
int& ref = vec[0]; // Ссылка на первый элемент

// ... добавляем много элементов, вызывая реаллокацию ...
for(int i=0; i < 100; ++i) vec.push_back(i);

// 💥 Вектор переехал. Старая память удалена.
// ref теперь указывает в мусор.
std::cout << ref; // Undefined Behavior (Crash или мусор)





🛡 Как лечить?

Если вы хотя бы примерно знаете, сколько элементов будет в векторе, всегда используйте reserve().


std::vector<User> users;
users.reserve(1000); // Сразу выделяем память под 1000 мест

// Теперь первые 1000 push_back будут дешевыми
// и гарантированно не вызовут реаллокации.



💡 Итог: std::vector это мощный инструмент, но за его автоматическое расширение платит процессор. Помогайте ему через reserve(), чтобы код был быстрым и безопасным.

#cpp #stdvector #performance #memory #coding #tips

➡️ @cpp_geek
  • 👍 7
  • ❤ 2
More from @cpp_geek
  1. Sep 24, 2026🎥 Вебинар по C++: Паттерн многопоточного программирования «Producer-Consumer» Когда неско…
  2. Sep 24, 2026Execution policy для параллельных алгоритмов Execution policy в C++ — это новшество, введе…
  3. Sep 17, 2026В чем разница между git fetch и git pull? Разница между этими командами заключается в том,…
  4. Sep 15, 2026std::tie std::tie — это функция, которая создает кортеж ссылок на lvalue из своих аргумент…
  5. Sep 11, 2026move constructor Move-конструктор — это специальный конструктор, который позволяет эффекти…
  6. Sep 9, 2026Move-only объекты и почему std::unique_ptr нельзя копировать Многие удивляются, когда комп…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →