Comment supprimer des éléments dans un vecteur. (effacer ne fonctionnera pas)

Lorsque je supprime des éléments dans un vecteur avec “effacer”, la mémoire n’est pas effacée. Par exemple, je crée un vecteur de la taille 2000. Après la création, le programme utilise 1,5 Mo de mémoire. Lorsque je fais l’effacement, rien ne sera effacé. Tous les éléments ont disparu. Mais ils sont toujours en mémoire.

Par exemple:

#include  #include  using namespace std; int main() { //Makes a vector of 2000 items vector test(200000); //Pause for test purpose system("pause"); //erase all elements test.erase(test.begin(),test.end()); //Pause for test purpose system("pause"); return false; } 

La taille renvoie 0. Mais le processus utilise toujours 1,5 Mo de mémoire.

erase ne libère pas la mémoire. Après le code en question test.capacity() >= 200000 est requirejs par la norme. Utilisation

 test.shrink_to_fit(); // in C++11 vector(test).swap(test); // in C++03 

réduire la capacité des vecteurs. Veuillez noter que cela ne garantit toujours pas que la mémoire utilisée par le rest du système sera supprimée. Le tas du processus ne peut pas être réduit en taille en général.

Le processus conserve la mémoire pour deux raisons:

  • std::vector ne redissortingbuera la mémoire que lorsqu’elle grandira, pas quand elle se rétrécira.
  • La mémoire libérée est souvent retenue par le processus pour être réutilisée.

En C ++ 11, les vecteurs ont une fonction membre shrink_to_fit , qui demandera au vecteur de réduire la quantité de mémoire allouée si possible. Il n’y a aucune garantie que cela le fera, cependant. En C ++ 03, ou si vous voulez vous assurer que la mémoire excédentaire est libérée, vous pouvez utiliser l’astuce consistant à échanger le vecteur avec un autre récemment alloué:

 std::vector(test).swap(test); 

ou si vous voulez l’effacer complètement:

 std::vector().swap(test); 

Cette astuce déplace la propriété de la mémoire allouée vers un vecteur temporaire; à la fin de l’expression, ce vecteur est détruit, libérant ainsi la mémoire.

Que la mémoire soit libérée ou non du processus dépend entièrement de la façon dont votre bibliothèque gère le magasin gratuit. Souvent, de petites allocations (jusqu’à quelques mégaoctets, peut-être) sont gérées par un tas – le processus demande de gros blocs de mémoire au système et les divise en petits morceaux. Les blocs ne peuvent pas être libérés à moins que tous les petits morceaux aient été libérés, et de nombreuses implémentations ne les libéreront pas encore.

Des allocations plus importantes peuvent être demandées directement depuis le système, auquel cas elles seront libérées une fois libérées.

Vous pouvez donc obtenir l’effet que vous attendez avec un code comme celui-ci:

 // A few gigabytes will probably be allocated directly. // You'll have to reduce this on a 32-bit system, or if there's not enough memory std::vector test(1000000000) // Use the "swap sortingck" to ensure the memory is deallocated. std::vector().swap(test); 

Mais rien ne garantit que cela libèrera la mémoire du processus; les détails de l’allocation de mémoire ne sont pas spécifiés par la norme et sont conformes à l’implémentation du compilateur / bibliothèque.

Vous voudrez peut-être le tester de cette façon:

 int main() { //Makes a vector of 2000 items { vector test(200000); //Pause for test purpose system("pause"); //erase all elements test.erase(test.begin(),test.end()); // Call erase or not, but destructor will be called here - freeing all memory } //Pause for test purpose system("pause"); return false; } 

vector.erase ne désalloue pas la mémoire à des fins simples – probablement la réutilisation de la mémoire allouée, plutôt que de la réallouer pour des demandes futures.

Lorsque le processus se termine, la mémoire est récupérée dans votre cas. Donc, il n’y a pas besoin d’effacer le vecteur.
Si vous souhaitez continuer à utiliser le vecteur dans une boucle, envisagez d’utiliser clear() qui efface le contenu du vecteur.
Si le vecteur est utilisé dans un object, une fois l’object détruit, le vecteur est également détruit.
Mais si le vecteur contient des pointeurs, vous devez les supprimer explicitement.