Подтвердить что ты не робот

С++ vector:: clear

vector <weight> decoy;

void clear_decoy() {  

    decoy.clear();   

    vector<weight> (decoy).swap(decoy);  
}

В приведенном выше методе clear_decoy(), что означает vector<weight> (decoy).swap(decoy); , пожалуйста?

Очищает ли метод decoy или нет? Спасибо!

4b9b3361

Ответ 1

Он создает новый вектор объектов Weight (который будет пустым) и заменяет его на decoy.

Причиной этого является то, что по умолчанию std::vector<t>::clear часто фактически не уменьшает хранилище, используемое вектором, оно просто уничтожает все содержащиеся там объекты. Таким образом, вектор имеет место для хранения большего количества объектов без перераспределения в будущем.

Иногда, однако, вы хотите обрезать емкость в векторе. Перемещение с помощью вновь созданного вектора (который живет до конца строки и, следовательно, разрушается там) освобождает всю память, выделенную вектором.

Ответ 2

Я никогда раньше не видел эту форму.

Я видел это как:

vector<weight>().swap(decoy);

Это означает, что "создайте новый пустой вектор и замените его на существующий.

vector<weight> (decoy).swap(decoy);

Чтобы понять это, перейдите к частям.

vector<weight>(decoy) создайте новый вектор (с его содержимым, скопированным из теперь пустой приманки). Новый вектор является анонимным временным, поэтому пусть оно и претендует на имя newvector.

newVector.swap(decoy); меняет новый вектор с помощью decopy.

(Обновлено для комментариев для исправления ошибок)

Ответ 3

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

Чтобы надежно освободить память, используйте следующее:

void clear_decoy() {  
    vector<weight>().swap(decoy);  
}

Это создает временный пустой вектор (с небольшим или отсутствующим распределением памяти), свопирует это с помощью decoy, так что память теперь принадлежит временному, а затем уничтожает временную, освобождая память.

Ответ 4

clear удаляет все записи из вектора, но необязательно освобождает пространство. Эта идиома свопинга восстанавливает вектор без выделения пространства.

Ответ 5

Как упоминается 0A0D, эффект swap заключается в обмене контролируемой памяти между двумя векторами. Но это требует немного большего объяснения.

Когда вы clear a vector, элементы удаляются из него, по крайней мере, до программиста. size() становится нулевым, а capacity() может изменяться или не изменяться. Но стандарт не гарантирует, что память, используемая вектором, будет фактически возвращена в операционную систему. Поэтому, если у вас было 1000 элементов в векторе перед clear(), и каждая из них занимала 1000-байтную память, после clear() вызывается каждый деструктор элемента, но вектор все равно может удерживаться в распределении по 1 000 000 байт.

Это иногда нежелательно. "Замечание об обмене", которое вы отмечаете выше, имеет эффект обмена контролируемой памятью между двумя векторами. Следовательно, decoy заканчивается управляемой памятью reset.

Вот что происходит шаг за шагом:

  • decoy каждый элемент erased. Деструкторы элементов и вектор size() обращается в нуль. Фактическая память может не освобождается.
  • В стеке создается новый вектор (vector<weight> (decoy)), а элементы из decoy копируются в него. Поскольку decoy был просто clear() ed, никакие элементы не копируются во временный вектор. Однако см. Править ниже. Вы не знаете, что контролируемая память не обменивается.
  • Временная векторная и decoy память обмениваются (.swap(decoy);), что приводит к тому, что decoy очищается, а память переносится на временную.
  • Временное отпадает от стека, в результате чего память освобождается.

Это называется трюк подкачки".

EDIT: Как отмечает Майк, оригинальный программист делает это неправильно. Временное не должно строиться на основе decoy, оно должно быть построено по умолчанию. Вы точно не знаете, что swap() будет копировать только элементы, а не контролируемую память внизу.

Ответ 6

С понятным,

Все элементы вектора упал: их деструкторы называются, и затем они удаляются из векторный контейнер, оставляя контейнер размером 0.

Swap просто меняет два вектора,

Содержимое свопинга

Обменивает содержимое вектора на содержимое vec, которое является другим вектор того же типа. Размеры могут различаются.

После вызова этого участника функции, элементы в этом контейнер - это те, которые были в vec перед вызовом, а также элементы vec - это те, которые были в этом. Все итераторы, ссылки и указатели остаются действительными для обмениваемых векторов.

Кажется, вы ничего не меняете и просто восстанавливаете распределение по умолчанию. Очистить можно освободить, но иногда это не так. Вы не только уменьшаете размер, но и уменьшаете пространство, выделенное оператором свопинга.