Разница между std :: resize (n) и std :: shrink_to_fit в C ++?


11

Я сталкивался с этими утверждениями:

resize(n)- Изменяет размер контейнера так, чтобы он содержал «n» элементов.
shrink_to_fit()- Уменьшает емкость контейнера до его размера и уничтожает все элементы, превышающие емкость.

Есть ли существенная разница между этими функциями? они попадают под векторы в C ++


resize изменяет размер контейнера, shrink_to_fit - нет. Для нормального использования вам не нужно знать о shrink_to_fit, он доступен только для того, чтобы позволить разработчикам вручную увеличить производительность своего кода.
NoSenseEtAl

2
Стандартные контейнеры имеют размер и вместимость . Размер - это текущее количество элементов в контейнере, а емкость - это объем выделенной памяти (примерно). Изменение размера изменяет размер, shrink_to_fitменяет емкость.
Какой-то программист чувак

2
Ты понимаешь разницу между capacityа size?
Куб

Ответы:


12

Векторы имеют два атрибута длины, которые означают разные вещи:

  • sizeколичество используемых элементов в векторе. Это количество вещей, которые вы сохранили. Это концептуальная длина.
  • capacity сколько элементов поместится в объем памяти, выделенный вектором

capacity >= sizeвсегда должно быть правдой, но нет никаких оснований для того, чтобы они всегда были равны. Например, когда вы удаляете элемент, для сокращения выделения потребуется создать новое выделение на один контейнер меньше и переместить оставшееся содержимое поверх («распределить, переместить, освободить»).

Точно так же, если capacity == sizeи вы добавите элемент, вектор может увеличить распределение на один элемент (другая операция «выделение, перемещение, освобождение»), но обычно вы собираетесь добавить более одного элемента. Если емкость должна увеличиться, вектор увеличит свою емкость более чем на один элемент, так что вы можете добавить еще несколько элементов, прежде чем переместить все снова.

Обладая этими знаниями, мы можем ответить на ваш вопрос:

  • std::vector<T>::resize()изменяет размер массива Если вы измените его размер меньше текущего размера, лишние объекты будут уничтожены. Если вы измените его размер больше его текущего размера, «новые» объекты, добавленные в конце, будут инициализированы по умолчанию.
  • std::vector<T>::shrink_to_fit()просит изменить емкость для соответствия текущему размеру. (Реализации могут или не могут удовлетворить этот запрос. Они могут уменьшить емкость, но не сделать ее равной размеру. Они могут вообще ничего не делать.) Если запрос будет выполнен, это отбросит часть или всю неиспользованную часть распределение вектора. Вы обычно используете это, когда вы закончите создание вектора и никогда не добавите к нему другой элемент. (Если вы заранее знаете, сколько предметов вы будете добавлять, было бы лучше использовать, std::vector<T>::reserve()чтобы сообщить вектору, прежде чем добавлять какие-либо элементы, вместо того, чтобы полагаться на shrink_to_fitчто-либо.)

Таким образом, вы используете, resize()чтобы изменить, сколько вещей концептуально в векторе.

Вы используете, shrink_to_fit()чтобы минимизировать избыточное пространство, которое вектор выделил внутри, не меняя, сколько вещей концептуально в векторе.


2
Обратите внимание, что shrink_to_fitэто не все или ничего. Реализация может уменьшить пропускную способность частично. Например, рассмотрим реализацию, которая ограничивает емкость вектора степенью двойки.
Франсуа Андриё

5

shrink_to_fit() - Уменьшает емкость контейнера до его размера и уничтожает все элементы, превышающие емкость.

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

В C ++, когда динамически используется память для объектов, есть два шага:

  1. Память выделяется для объектов.
  2. Объекты инициализируются / создаются в ячейках памяти.

Когда объекты в динамически распределенной памяти удаляются, есть также два шага, которые отражают шаги построения, но в обратном порядке:

  1. Объекты в ячейках памяти разрушены (для встроенных типов это просто тупик).
  2. Память, используемая объектами, освобождается.

Памяти , выделенные за пределами размера контейнера просто буфер. Они не содержат должным образом инициализированных объектов. Это просто сырая память. shrink_to_fit()гарантирует, что дополнительной памяти нет, но в этих местах не было объектов. Следовательно, ничто не разрушается, только память освобождается.


2

Согласно стандарту C ++ относительно shrink_to_fit

Эффекты: shrink_to_fit - это необязательный запрос для уменьшения емкости () до размера ().

и относительно resize

Эффекты: Если sz <size (), удаляет последние элементы size () - sz из последовательности. В противном случае добавляет sz - size () вставленные по умолчанию элементы в последовательность.

Очевидно, что функции делают разные вещи. Более того, первая функция не имеет параметров, а вторая функция имеет даже два параметра. Функция shrink_to_fitне меняет размер контейнера, хотя может перераспределять память.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.