Как уменьшить размер std :: vector?

Есть ли способ изменить размер std::vector на меньшую емкость, когда мне больше не нужно ранее зарезервированное пространство?


person bombardier    schedule 31.10.2008    source источник


Ответы (5)


Эффективный STL, Скотт Мейерс, пункт 17: Используйте трюк swap, чтобы сократить избыточную емкость.

vector<Person>(persons).swap(persons);

После этого persons "усаживается, чтобы соответствовать".

Это основано на том факте, что конструктор копирования vector выделяет ровно столько памяти, сколько необходимо для копируемых элементов.

person Sébastien RoccaSerra    schedule 31.10.2008
comment
Предложите исправление грамматики: «сжался», а не «сжался» - person James Hopkin; 31.10.2008
comment
Хороший. Вы, может быть, знаете, почему они не реализовали это как метод, поскольку он выглядит как обычный вариант использования контейнера? - person bombardier; 31.10.2008
comment
После того, как вектор выделил буфер, трудно удалить [] конец этого буфера. И это просто гарантирует, что будущие вставки потребуют выделения нового буфера и копирования в него всего (аннулирование итераторов). - person Max Lybbert; 31.10.2008

Если вы используете C ++ 11, вы можете использовать vec.shrink_to_fit(). По крайней мере, в VS2010 это поможет вам сделать свопинг.

person Alex Korban    schedule 01.03.2012
comment
Это не эквивалент трюка с заменой. shrink_to_fit - это необязательный запрос, и ему разрешено ничего не делать. - person Cat Plus Plus; 02.03.2012
comment
Я сказал в VS2010, но да, на других компиляторах он может этого не делать. - person Alex Korban; 02.03.2012
comment
@CatPlusPlus shrink_to_fit, по всей вероятности, сделает трюк с подкачкой или realloc, но с небольшой векторной оптимизацией, которая все равно не сбросит capacity() для соответствия size(), потому что нет выделения кучи для сжатия. Я думаю, что это причина, по которой он указан как необязательный. - person Potatoswatter; 29.04.2012

Создайте новый временный вектор из существующего, затем вызовите метод swap для существующего, передав временный. Позвольте временному (теперь со старым, негабаритным буфером) выйти из области видимости.

Привет, ваш вектор имеет именно тот размер, который соответствует его содержимому.

Если это звучит как много копирования и выделения - имейте в виду, что это то, что вектор делает каждый раз, когда ему все равно приходится перераспределять свой текущий зарезервированный предел.

[Edit] Да, я просто сказал то же самое, что и Себастьен, несколькими словами. Другой случай состояния гонки stackoverflow ;-)

person philsquared    schedule 31.10.2008
comment
Что ж, я проголосовал за тебя, Фил, потому что твой ответ все еще полезен, даже если ты не был первым, кто его опубликовал! :-) - person Onorio Catenacci; 31.10.2008

Уловка подкачки - это эффективный способ уменьшить емкость объекта, он меняет местами содержимое моего вектора на вновь созданный путем создания копии:

vector<Person>(persons).swap(persons);

Обратите внимание, что нет никакой гарантии, что people.capacity (); после трюка подкачки равен размеру: емкость вектора (человек) - это емкость, которую реализация библиотеки резервирует для векторов размераpersize ().

В C ++ 11 появилась функция shrink_to_fit ().

shrink_to_fit (), а также трюк с заменой не гарантируют, что размер емкости будет эффективно уменьшен до размера вектора.

В любом случае shrink_to_fit () может сделать ваши итераторы недействительными (если происходит перераспределение) или не может: это зависит от фактической реализации библиотеки.

Имейте в виду, что трюк со свопингом требует, чтобы person.size () копировали конструкции деструкций Person и person.size (). Shrink_to_fit () может избежать всего этого копирования и оставить ваши итераторы действительными. Мог. Но время от времени случается, что shrink_to_fit () реализуется в рамках трюка с подкачкой ...

person jimifiki    schedule 20.11.2013
comment
Не могли бы вы указать, где указано, что shrink_to_fit() должен быть реализован с точки зрения swap()? - person Toby Speight; 27.07.2017
comment
@TobySpeight спасибо за замечание. Может, мой английский недостаточно хорош. Я имел в виду, что, поскольку shrink_to_fit () может быть реализован в терминах трюка подкачки, иногда он реализуется таким образом. Разрешите отредактировать ответ. Если мне это не удастся, не стесняйтесь редактировать ответ, чтобы улучшить его качество. Ваш вклад будет приветствоваться. Спасибо - person jimifiki; 31.07.2017

Вы ищете эквивалент QVector :: squeeze и я Боюсь, этого явно не существует в STL. Обратитесь к ответу Себастьяна, если он подходит для вашей реализации STL.

person fulmicoton    schedule 31.10.2008