Есть ли способ изменить размер std::vector
на меньшую емкость, когда мне больше не нужно ранее зарезервированное пространство?
Как уменьшить размер std :: vector?
Ответы (5)
Эффективный STL, Скотт Мейерс, пункт 17: Используйте трюк swap
, чтобы сократить избыточную емкость.
vector<Person>(persons).swap(persons);
После этого persons
"усаживается, чтобы соответствовать".
Это основано на том факте, что конструктор копирования vector
выделяет ровно столько памяти, сколько необходимо для копируемых элементов.
Если вы используете C ++ 11, вы можете использовать vec.shrink_to_fit()
. По крайней мере, в VS2010 это поможет вам сделать свопинг.
shrink_to_fit
- это необязательный запрос, и ему разрешено ничего не делать.
- person Cat Plus Plus; 02.03.2012
shrink_to_fit
, по всей вероятности, сделает трюк с подкачкой или realloc
, но с небольшой векторной оптимизацией, которая все равно не сбросит capacity()
для соответствия size()
, потому что нет выделения кучи для сжатия. Я думаю, что это причина, по которой он указан как необязательный.
- person Potatoswatter; 29.04.2012
Создайте новый временный вектор из существующего, затем вызовите метод swap для существующего, передав временный. Позвольте временному (теперь со старым, негабаритным буфером) выйти из области видимости.
Привет, ваш вектор имеет именно тот размер, который соответствует его содержимому.
Если это звучит как много копирования и выделения - имейте в виду, что это то, что вектор делает каждый раз, когда ему все равно приходится перераспределять свой текущий зарезервированный предел.
[Edit] Да, я просто сказал то же самое, что и Себастьен, несколькими словами. Другой случай состояния гонки stackoverflow ;-)
Уловка подкачки - это эффективный способ уменьшить емкость объекта, он меняет местами содержимое моего вектора на вновь созданный путем создания копии:
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 () реализуется в рамках трюка с подкачкой ...
shrink_to_fit()
должен быть реализован с точки зрения swap()
?
- person Toby Speight; 27.07.2017
Вы ищете эквивалент QVector :: squeeze и я Боюсь, этого явно не существует в STL. Обратитесь к ответу Себастьяна, если он подходит для вашей реализации STL.