vector decoy; void clear_decoy() { decoy.clear(); vector (decoy).swap(decoy); }
Dans la méthode ci-dessus clear_decoy()
, que fait le vector (decoy).swap(decoy);
signifie s’il vous plaît?
Est-ce que la méthode efface decoy
ou pas? Merci!
Il crée un nouveau vecteur d’objects Weight
(qui sera vide) et l’échange avec decoy
.
La raison en est que par défaut, std::vector
ne réduit souvent pas réellement le stockage utilisé par un vecteur, il détruit simplement tous les objects qu’il contient. De cette manière, le vecteur a la possibilité de stocker plus d’objects sans réaffectation ultérieure.
Cependant, vous souhaitez parfois réduire la capacité du vecteur. L’échange avec un vecteur nouvellement créé (qui vit jusqu’à la fin de sa ligne et est donc détruit là) libère toute la mémoire allouée par le vecteur.
Je n’ai jamais vu cette forme auparavant.
Je l’ai vu écrit comme:
vector().swap(decoy);
Ce qui signifie “créer un nouveau vecteur vide et l’échanger avec le vecteur existant.
vector
Pour comprendre cela, casser en plusieurs parties.
vector
crée un nouveau vecteur (avec son contenu copié à partir du leurre vide). Le nouveau vecteur est un temporaire anonyme, alors supposons qu’il s’appelle newvector
.
newVector.swap(decoy);
échange le nouveau vecteur avec decopy.
(Mis à jour par commentaires pour corriger un bug)
Ce code est une tentative infructueuse d’utilisation d’une astuce commune pour s’assurer que la mémoire allouée par le vecteur est libérée. Cela peut ou non être le cas, selon que le constructeur de copie du vecteur alloue ou non de la mémoire à la taille de l’autre vecteur ou à sa capacité.
Pour libérer la mémoire de manière fiable, utilisez les éléments suivants:
void clear_decoy() { vector().swap(decoy); }
Cela crée un vecteur vide temporaire (avec peu ou pas de mémoire allouée), l’échange avec un decoy
afin que la mémoire soit maintenant la propriété du temporaire, puis détruit le temporaire et libère la mémoire.
clear
supprime toutes les entrées du vecteur, mais ne libère pas nécessairement l’espace. Cet idiome d’échange rétablit le vecteur sans espace alloué.
Comme mentionné par 0A0D, l’ swap
pour effet d’ swap
la mémoire contrôlée sous-jacente entre les deux vecteurs. Mais cela mérite un peu plus d’explication.
Lorsque vous clear
un vector
, les éléments en sont supprimés au moins pour le programmeur. size()
devient zéro et la capacity()
peut ou non changer. Toutefois, la norme ne garantit pas que la mémoire utilisée par le vecteur sera réellement restituée au système d’exploitation. Donc, si vous aviez 1000 éléments dans le vecteur avant clear()
et que chacun prenait 1 000 octets en mémoire, après le clear()
, le destructeur de chaque élément est appelé, mais le vecteur peut toujours conserver une allocation de 1 000 000 octets.
Ceci est parfois indésirable. Le «truc d’échange» que vous avez noté ci-dessus a pour effet d’échanger la mémoire contrôlée entre les deux vecteurs. Par conséquent leur decoy
se termine avec sa réinitialisation contrôlée de la mémoire.
Voici ce qui se passe pas à pas:
decoy
éléments de decoy
sont chacun erased
. Les destructeurs des éléments sont appelés et la size()
du vecteur size()
devient zéro. La mémoire réelle ne peut pas être désallouée. vector (decoy)
) et les éléments du decoy
sont copiés. Puisque leur decoy
venait juste d’être clear()
, aucun élément n’est copié dans le vecteur temporaire. Cependant, voir modifier ci-dessous. Vous ne savez pas que la mémoire contrôlée n’est pas échangée. decoy
est échangée ( .swap(decoy);
), le decoy
étant ainsi effacé et sa mémoire transférée vers le temporaire. C’est ce que l’on appelle ” le truc d’échange “.
EDIT: Comme Mike le mentionne, le programmeur original fait les choses mal. Le temporaire ne doit pas être construit à partir d’un decoy
, il doit simplement être construit par défaut. Vous ne savez pas avec certitude que swap()
ne fera que copier les éléments et non la mémoire contrôlée située en dessous.
Avec clair,
Tous les éléments du vecteur sont supprimés: leurs destructeurs sont appelés, puis ils sont supprimés du conteneur de vecteur, le conteneur ayant une taille de 0.
Swap échange juste les deux vecteurs,
Contenu d’échange
Echange le contenu du vecteur par le contenu de vec, qui est un autre vecteur du même type. Les tailles peuvent différer.
Après l’appel de cette fonction membre, les éléments de ce conteneur sont ceux qui étaient dans vec avant l’appel et les éléments de vec sont ceux qui y figuraient. Tous les iterators, références et pointeurs restnt valables pour les vecteurs échangés.
Il semble que vous n’échangiez rien et que vous restauriez simplement l’allocation par défaut. Clear peut désallouer mais parfois pas. Vous réduisez non seulement la taille mais réduisez également l’espace alloué avec l’instruction swap.