Vecteur C ++ :: clear

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::clear 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 (decoy).swap(decoy);

Pour comprendre cela, casser en plusieurs parties.

vector(decoy) 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:

  1. 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.
  2. Un nouveau vecteur est construit sur la stack ( 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.
  3. La mémoire du vecteur temporaire et du decoy est échangée ( .swap(decoy); ), le decoy étant ainsi effacé et sa mémoire transférée vers le temporaire.
  4. Le temporaire tombe de la stack, ce qui entraîne la libération de la mémoire.

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.