Разница между std :: resize (n) и std :: shrink_to_fit в C ++? - PullRequest
11 голосов
/ 25 февраля 2020

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

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

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

Ответы [ 3 ]

12 голосов
/ 25 февраля 2020

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

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

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

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

С этим знанием мы можете ответить на ваш вопрос:

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

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

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

5 голосов
/ 25 февраля 2020

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

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

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

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

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

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

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

2 голосов
/ 25 февраля 2020

В соответствии со стандартом C ++ относительно shrink_to_fit

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

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

Эффекты: Если sz

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...