STL: pb mémoire "physique" non libérée avec un vector

Signaler
Messages postés
29
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
16 juin 2008
-
Messages postés
29
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
16 juin 2008
-
Bonjour à tous, j'utilise des vecteurs pour stocker des objets 3d, ors la mémoire physique utilisée par le vecteur au fur et à mesure de ses besoins n'est pas libérée mais gardée comme "réservoir" pour optimiser les futures insertions/suppression sans avoir à réallouer, opération couteuse s'il en est.
Existe t il un moyen de libérer la totalité de la mémoire physique ou revenir au début (juste après le new du vecteur ) sans avoir à le supprimer/recréer ?
Merci de vos réponses

code de test :
vector *t=new vector; //mem=2.7Mb size=0 capacity=0
t->reserve (10000000);               //mem=2.7Mb size=0 capacity=10000000
for (int i=0;i<10000000;i++) t->push_back(2);  //mem=41.8Mb size=10000000 capacity=10000000
t->resize (5000000);                  //mem=41.8Mb size=5000000   capacity=10000000
t->clear();                                 //mem=41.8Mb size=10000000 capacity=10000000
delete t;                                   //
t=new vector;                    //mem=2.7Mb size=0 capacity=0

16 réponses

Messages postés
416
Date d'inscription
vendredi 31 janvier 2003
Statut
Membre
Dernière intervention
19 décembre 2013
2
Salut,

1) si tu peux eviter l'allocation du vecteur sur le tas , c une bonne idee
2) si la memoire allouee te derange tu pourrais implementer toi meme un container de stockage , ca pourrait une idee la dans ce cas tu controllerait la taille de memoire allouee.

ce sont juste des idees. salut

http://liveplayaz.com

je suis heureux de faire partie d'une grande famille ...!
Messages postés
29
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
16 juin 2008

C déjà le cas au niveau de l'allocation, et je n'avais pas envie de "jouer" avec l'Allocator, la STL est sensée être une toolbox integrated, mais merci qd même Nicki
...
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Ca sert a rien d'allouer un std::vector dans le tas:

{
vector t;t.reserve (10000000);               //mem2.7Mb size0 capacity= 10000000
for (int i=0;i<10000000;i++) t.push_back(2);  //mem=41.8Mb size=10000000 capacity=10000000
t.resize (5000000);                  //mem=41.8Mb size=5000000   capacity=10000000
t.clear();                                 //mem=41.8Mb size= 10000000 capacity =10000000
}

J'ai pas tout a fait la meme chose, lorsque je fais le test. tout d'abord je comprend pas ta valeur en rouge car 10 millions d'entiers, ca fait a peu près 40Mo.
De meme la valeur en bleu, c'est 0. Donc je comprend pas pk tu mets 10E6. Petite erreur lors du post ?

Sinon, je vois pas cmt forcer le conteneur a libérer toute sa mémoire.
Messages postés
29
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
16 juin 2008

Salut, regarde plus bas, c sera  plus clair que mon prec post.
et quand on a une dizaine de vecteurs qui sont joueurs en taille ca devient intéressant au bout d'un moment
....

void test_vector()
{
vector *t;
cout<<endl<<"before allocation.."; getche (); //mem=2724Kb
t=new vector;
cout<<endl<<"after allocation .."<<" size="<<t->size()<<" capa="<<t->capacity(); getche (); //mem=2736Kb
t->reserve (10000000);
cout<<endl<<"after allocation.."<<" size="<<t->size()<<" capa="<<t->capacity(); getche ();//mem=2744Kb
for (int i=0;i<10000000;i++) t-> push_back(i);
cout<<endl<<"after filling.."<<" size="<<t->size()<<" capa="<<t->capacity(); getche ();//mem=41880Kb
t->clear();
cout<<endl<<"after clearing.."<<" size="<<t->size()<<" capa="<<t->capacity(); getche ();//mem=41880Kb
delete t;
cout<<endl<<"after deleting.."; getche ();     //mem=2772Kb
}

result:
before allocation..
after allocation .. size=0 capa=0
after allocation.. size=0 capa=10000000
after filling.. size=10000000 capa=10000000
after clearing.. size=0 capa=10000000
after deleting..
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Il y a toujours une petite erreur:
vector *t;
cout<<endl<<"before allocation.."; getche (); //mem=2724Kb
t=new vector;
cout<<endl<<"after
allocation .."<<" size="<<t->size()<<"
capa="<<t->capacity(); getche (); //mem=2736Kb
t->reserve (10000000);
cout<<endl<<"after
allocation.."<<" size="<<t->size()<<"
capa="<<t->capacity(); getche ();//mem=2744Kb

En rouge, c'est 41880Kb que l'on a, et non 2744. Le "reserve" alloue la mémoire.
Mais bon, ca ne change rien a ton pb.
Messages postés
29
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
16 juin 2008

Sorry mais il n'y en a pas, resrve() n'est pas resize().

void reserve(size_type n);




Increases the capacity of self in anticipation of adding new elements. reserve itself does not add any new elements. After a call to reserve, capacity() is greater than or equal to n and subsequent insertions will not cause a reallocation until the size of the vector exceeds n. Reallocation does not occur if n is less than capacity(). If reallocation does occur, then all iterators and references pointing to elements in the vector are invalidated. reserve takes at most linear time in the size of self. reserve throws a length_error exception if n is greater than max_size().
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Bien sur que si il y en a. C'est meme l'intéret de reserve. Ca permet de réserver l'espace mémoire pour éviter des réallocations inutiles lorsque l'on sait quel taille, on va avoir besoin tout en utilisant push_back. On pourrait bien sur faire un resize et utiliser l'opérateur [], ca reviendrait au meme.

Voila, tu as mis la définition, et c'est plus ou moins clairement expliquer. Grace a Reserve, on augmente la capacité du conteneur. La capacité est le nombre d'élément que l'on pourra insérer sans provoquer de réallocation. Ca me semble clair. La mémoire est allouée par Reserve.
Messages postés
29
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
16 juin 2008

Désolé tu as raison je pensais qu'il s'agissait d'assignation d'éléments, reserve n'en fait pas alors que resize oui, d'où mon soulignement en gras. Il n'en demeurre pas moins que mes traces avec le code ci-dessus par le task manager n'affiche pas la taille finale de 42Mb tant que des push_back n'ont pas été effectués.
... 
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
En effet, j'ai testé avec devpp et Visual C++ et je n'ai pas le meme comportement. j'ai du mal a comprendre pourquoi.
Alors qu'avec Visual, le "reserve" alloue clairement les 40 Mo puisque je le vois nettement lorsque je debug ligne par ligne en ayant le gestionnaire des taches ouvert. Par contre, sous devcpp, (comme tu dis) je ne vois aucune allocation. Alors je me suis dis que peut etre, l'allocation sera faite lors de la première insertion mais ce n'est pas le cas.

Donc il faudrait creuser d'avantage et regarder le code source directement mais ca m'intéresse pas particulièrement :)
Messages postés
29
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
16 juin 2008

certes ce que je fais actuellement ....sachant que j'ai testé avec d'autres compilateurs ayant leurs propres implémentations de la STL ou SGI et idem comportements non équivalents, d'où ma quête et interrogations
...
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Bon finalement, j'ai jeté un coup d'oeil en débuggant avec devcpp et conclusion: je comprends pas, car l'allocation a bien lieu. En tout cas, une fonction Allocate est bien appelée. Mais je m'arreterais la, puisque je n'utilise que Visual de toute facon.
Ceci dit, ca m'étonne un peu que cette simple fonction "reserve" n'est pas un comportement standard pour différentes implémentations de la STL.
Messages postés
29
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
16 juin 2008

Ta drnière assertion est le noeud gordien de mon interrogation mais est tout bonnement inenvisageable donc where is the failure ?
...
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
I dont have any idea. Mais si tu as dois manipuler des grands tableaux, tu peux gérer toi meme la mémoire à coup de new/delete[].
Messages postés
29
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
16 juin 2008

ce que j'ai +/- tjrs fait mais il faut savoir utiliser les outils (algorithmie de base de tri/recherche....) mis à sa disposition sans réinventer (ré écrire) la roue à tout bout de champs d'où un mix savant entre tableau et STL.
Si l'exercice peut s'avérer plaisant, il y a des moments où cela coincide mal avec efficacité/rapidité/robustesse/... et fatigue oups je l'avais oublié celui-là :)
bonne soirée
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Oui mais gérer soi meme l'allocation d'un tableau, ca n'est pas vraiment réinventer la roue. Tu peux appliquer des aglos de la STL sur des tableaux, pas uniquement sur des conteneurs de la STL.
Messages postés
29
Date d'inscription
lundi 10 janvier 2005
Statut
Membre
Dernière intervention
16 juin 2008

certes