2009-08-07 5 views
9

J'utilise un std::deque pour stocker un assez grand nombre d'objets. Si je supprime un tas de ces objets, il me semble que son utilisation de la mémoire ne diminue pas, de la même manière que std :: vector.Comment libérer de la mémoire à partir de std :: deque?

Y a-t-il un moyen de le réduire? Je sais que dans un vecteur, vous devez utiliser le «swap trick», ce que je suppose fonctionnerait ici aussi, mais je préfère éviter cela car cela nécessiterait de copier tous les éléments laissés dans le conteneur (et nécessite donc que vous ayez assez de mémoire pour stocker chaque objet deux fois). Je ne suis pas intimement familier avec la mise en œuvre de deque, mais ma compréhension de cela est qu'il pourrait être possible de réaliser une telle chose sans beaucoup de copies (alors qu'avec un vecteur ce n'est clairement pas le cas). J'utilise le STL VC++ (Dinkumware), si cela fait une différence.

+2

Avez-vous établi que votre implémentation deque ne libère pas déjà des blocs de mémoire dès que suffisamment d'éléments ont été supprimés pour les vider? Ou est-ce que vous voulez vraiment presser les derniers octets en réaffectant le bloc à chaque extrémité? –

+0

Je pense ainsi, d'une manière assez rude et prêt: J'ajoute 100.000 articles -> L'utilisation de la mémoire est ~ 90MB. J'ajoute un autre 100.000 -> l'utilisation de la mémoire est ~ 170MB. Je retire 100.000 articles -> l'utilisation de la mémoire est encore ~ ​​170MB. Ajouter encore 100.000 -> encore 170. Je suppose que 100.000 articles est plus que suffisant qu'il aurait des blocs vides qu'il aurait libérés s'il allait. – Peter

+5

Utilisation de mémoire du processus ou utilisation de la mémoire de la collection? Tout simplement parce que la collection libère la mémoire ne signifie pas qu'elle retourne au système d'exploitation, alors essayez d'allouer 80 Mo de tableau char après avoir supprimé les éléments, et voyez si l'utilisation va à 250 Mo ou reste à 170. Excuses si vous connaissez déjà tout cela choses et ont pris en compte pour cela - des millions ne le feraient pas. –

Répondre

14

Il n'y a aucun moyen de le faire directement dans un fichier std :: deque. Cependant, il est facile de le faire en utilisant un temporaire (ce qui est fondamentalement ce qui se passe dans un vecteur std :: lorsque vous réduisez sa capacité).

Voici un good article on std::deque, en le comparant à std :: vector. Tout en bas montre un moyen propre d'échanger et de rétrécir un vecteur, qui fonctionne de la même manière avec deque.

+0

Merci. Je soupçonnais qu'il n'y aurait peut-être aucun moyen de le faire, mais il semble que ce devrait être possible ... J'ai expliqué dans la question pourquoi je répugne à utiliser la chose d'échange dans ce cas, mais peut-être que je vais doit regarder dans tout ça. – Peter

+0

Peter - la meilleure option avec le "swap" chose est d'utiliser des éléments alloués par tas. Dans ce cas, vous ne faites qu'une copie des références, au lieu d'une copie de tous les éléments plus leur mémoire. C'est assez mineur, typiquement. –

+0

La fonction swap n'échange que les pointeurs internes du vecteur, pas les éléments eux-mêmes. – Karu

4

La taille de mémoire d'une mémoire peut être réduite ou non. Lorsque et Comment cela se produit est spécifique à l'implémentation. Malheureusement, vous n'avez pas beaucoup de contrôle manuel car les deques manquent même de capacité() ou de réserve().

Je suggérerais swap() si vous détectez effectivement la libération de la mémoire n'est pas effectuée à votre convenance.

Une connaissance intime de la gestion de la mémoire deque peut probablement tirer de site Dikum (ceci est votre implémentation actuelle, non?)

1

std :: deque retournera mémoire à son allocateur. Souvent, cet allocateur ne renvoie pas la mémoire au système d'exploitation. Dans de tels cas, il semble que la mémoire ne soit pas "libérée". Les bons détecteurs de fuite de mémoire seront satisfaits dès que la mémoire est retournée à l'allocateur, et comprennent que toute la mémoire n'est pas libérée par free().

3

Comme ajouté des informations à ceci:

En C++ 0x/C++ 11, deque (et plusieurs autres conteneurs) a une nouvelle fonction appelée « shrink_to_fit » qui supprimera les articles excédentaires et aligner essentiellement la capacité() == size()

+0

capacity() peut toujours être supérieur à size() après shrink_to_fit() - il s'agit d'une requête non-obligatoire; 'void shrink_to_fit() {}' est une implémentation parfaitement légale, en fait. Mais même avec une bonne implémentation, capacity() peut être plus grande que size(), par exemple si le conteneur a trop peu d'éléments, il peut quand même valoir la peine d'allouer plus de mémoire. (Pensez aux conteneurs vides.) – Lrdx

Questions connexes