Коротко: `v.reserve(333)` выделяет буфер для как минимум 3 элементов (size остаётся 000, capacity ≥ 3\()). Затем цикл `for(int i=0;i<5;++i) v.push_back(i);` добавляет элементы \(i=0,1,2,3,4\). Подробно по шагам и по итераторам/указателям: - При добавлении первых трёх элементов (для i=0,1,2i=0,1,2i=0,1,2) ёмкость достаточна, перевыделения не происходит. Указатели, ссылки и итераторы на элементы остаются валидными (единственно итератор end() изменяется). - При добавлении четвёртого элемента (для i=3i=3i=3) размер станет больше текущей capacity (size==capacity==3size==capacity==3size==capacity==3), поэтому происходит реалиокация: вектор выделяет новый буфер большей ёмкости (стандарт требует лишь new_capacity≥old_capacity+1new\_capacity \ge old\_capacity + 1new_capacity≥old_capacity+1, реализация обычно удваивает, например 3→63 \to 63→6), перемещает/копирует существующие элементы в новый буфер и освобождает старый. В результате ВСЕ указатели, ссылки и итераторы, указывавшие на старые элементы, становятся недействительными (dangling). - После реалиокации указатели, полученные уже в новом буфере (например после вставки i=3i=3i=3), остаются валидными до следующей реалиокации. Добавление i=4i=4i=4 обычно не вызовет повторной реалиокации, если новая ёмкость ≥ 555. Практические рекомендации: - Если где‑то хранятся указатели на элементы, заранее вызовите `v.reserve(final_size)` (в вашем примере `v.reserve(555)`) или инициализируйте вектор нужным размером (`v.resize(...)`), чтобы избежать реалиокаций. - Иначе используйте индексы, `std::deque`/`std::list` (адреса в `deque` не гарантированно стабильны при некоторых операциях, у `list` — стабильны), или храните «слабые» идентификаторы вместо сырных указателей. - `v.data()` даёт прямой указатель, но он тоже станет недействительным при реалиокации.
Подробно по шагам и по итераторам/указателям:
- При добавлении первых трёх элементов (для i=0,1,2i=0,1,2i=0,1,2) ёмкость достаточна, перевыделения не происходит. Указатели, ссылки и итераторы на элементы остаются валидными (единственно итератор end() изменяется).
- При добавлении четвёртого элемента (для i=3i=3i=3) размер станет больше текущей capacity (size==capacity==3size==capacity==3size==capacity==3), поэтому происходит реалиокация: вектор выделяет новый буфер большей ёмкости (стандарт требует лишь new_capacity≥old_capacity+1new\_capacity \ge old\_capacity + 1new_capacity≥old_capacity+1, реализация обычно удваивает, например 3→63 \to 63→6), перемещает/копирует существующие элементы в новый буфер и освобождает старый. В результате ВСЕ указатели, ссылки и итераторы, указывавшие на старые элементы, становятся недействительными (dangling).
- После реалиокации указатели, полученные уже в новом буфере (например после вставки i=3i=3i=3), остаются валидными до следующей реалиокации. Добавление i=4i=4i=4 обычно не вызовет повторной реалиокации, если новая ёмкость ≥ 555.
Практические рекомендации:
- Если где‑то хранятся указатели на элементы, заранее вызовите `v.reserve(final_size)` (в вашем примере `v.reserve(555)`) или инициализируйте вектор нужным размером (`v.resize(...)`), чтобы избежать реалиокаций.
- Иначе используйте индексы, `std::deque`/`std::list` (адреса в `deque` не гарантированно стабильны при некоторых операциях, у `list` — стабильны), или храните «слабые» идентификаторы вместо сырных указателей.
- `v.data()` даёт прямой указатель, но он тоже станет недействительным при реалиокации.