Вектор C++::ясно

vector <weight> decoy;

void clear_decoy() {  

    decoy.clear();   

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

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

Делает четкий метод decoy или нет?Спасибо!

23
задан Justin Ardini 13 August 2010 в 14:24
поделиться

6 ответов

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

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

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

20
ответ дан 29 November 2019 в 01:08
поделиться

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

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

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

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

10
ответ дан 29 November 2019 в 01:08
поделиться

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

6
ответ дан 29 November 2019 в 01:08
поделиться

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

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

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

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

  1. элементы decoy каждый стираются. Деструкторы элементов вызываются, и размер() вектора становится равным нулю. Фактическая память может не может быть деаллоцирована.
  2. На стеке создается новый вектор (vector (decoy)) и в него копируются элементы из decoy. Поскольку decoy был только что clear()ed, никакие элементы не копируются во временный вектор. Однако, см. правку ниже. Вы не знаете, что управляемая память не подкачивается.
  3. Память временного вектора и decoy меняются местами (.swap(decoy);), в результате чего decoy очищается, а его память передается временному.
  4. Временная падает со стека, в результате чего ее память деаллоцируется.

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

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

3
ответ дан 29 November 2019 в 01:08
поделиться

Если ясно,

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

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

Swap content

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

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

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

1
ответ дан 29 November 2019 в 01:08
поделиться

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

Я видел, что это написано так:

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

Что означает «создать новый пустой вектор и заменить его существующим.

vector (приманка) .swap (приманка);

Чтобы поймите это, разбейте его на части.

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

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

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

22
ответ дан 29 November 2019 в 01:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: