multidim stl vector memory leak
-
Und selbst wenn man den vector explizit zwingt, den Speicher wieder freizugeben, heißt das noch lange nicht, dass er dadurch anderen Programmen zur Verfügung steht (Kommt auf das Betriebssystem an, das Zurückholen von freiem Speicher vor Prozessende ist aber eher ungewöhnlich). Lediglich andere Teile deines Programms können diesen Speicher dann nutzen.
-
drakon schrieb:
Viele Implementierungen von std::vector geben den Speicher, den sie einmal angefordert haben nicht frei und daher ist das ganz normal. Wenn du einen std::vector wirklich leeren möchtest, dann mach das so:
std::vector<int> v; // fülle v v = std::vector<int> ();Das hilft IIRC auch nicht, sondern leert auch nur v. Der behält seinen Speicher trotzdem bein. Wirklich gelöscht wirds durch swap:
std::vector<int> v; // fülle v v.swap(std::vector<int>())
-
Danke janjan docshoe:
http://www.codeproject.com/KB/stl/stl_ml.aspx
überträgt denn der vector nicht einen Zeiger auf den Wert?
Sollte etwa kein clean oder remove durchgeführt werden?
Nunja wenn man die Schleife mit 100 000 Objekte füllt wird schon ziemlich alloziert. Mit clear kommt wird fast alles wieder freigegeben.
-
@pumuckl
Stimmt. Habe ich nicht mehr dran gedacht.
-
hier noch ein Bsp.
void foo() { vector<vector<vector<string>>>vcat; for (int x=0; x<100000; x++) { vector<vector<string>>twodim; vcat.push_back(twodim); for (int y=0; y<5; y++) { vector<string>onedim; vcat[x].push_back(onedim); vcat[x][y].push_back("test"); } } vcat.clear(); }
-
fragesteller1 schrieb:
Danke janjan docshoe:
http://www.codeproject.com/KB/stl/stl_ml.aspx
überträgt denn der vector nicht einen Zeiger auf den Wert?Das ist jetzt das dritte Paar Schuhe...
Im dem Fall, wo lediglich Zeiger auf Objekte in einem Vektor verwaltet werden ruft der Vektor beim Löschen lediglich den Destruktor für Zeiger auf, aber nicht den Destruktor für das Objekt, auf das der Zeiger zeigt. In deinem Fall mag das ja Sinn machen, aber es gibt Fälle, wo man das eben nicht möchte.
boost/TR1 bieten da einige Möglichkeiten, um das automatische Freigeben auch für Zeiger in Containern (smart pointer, pointer container).
-
pumuckl schrieb:
Das hilft IIRC auch nicht, sondern leert auch nur v. Der behält seinen Speicher trotzdem bein. Wirklich gelöscht wirds durch swap:
std::vector<int> v; // fülle v v.swap(std::vector<int>())Das war mir auch noch nicht bekannt. Gibt vector den allokierten Speicher nicht im Destruktor wieder frei?
-
Doch, aber in dem Beispiel wird nirgendwo der Destruktor aufgerufen:
std::vector<int> v; // fülle v v = std::vector<int> ();
-
v.swap(std::vector<int>())Das wird so nicht kompilieren, da RValues nicht an Non-Const-Referenzen gebunden werden. Richtig wäre
std::vector<int>().swap(v);
-
DocShoe schrieb:
Doch, aber in dem Beispiel wird nirgendwo der Destruktor aufgerufen:
Entweder meinen wir verschiedene Beispiele, aber in dem vom Eröffnungspost werden nur statische Objekte verwendet. Der Destruktor wird am Routinenende also aufgerufen.
-
FrEEzE2046 schrieb:
Entweder meinen wir verschiedene Beispiele, aber in dem vom Eröffnungspost werden nur statische Objekte verwendet. Der Destruktor wird am Routinenende also aufgerufen.
Dann verstehe ich die Frage nicht. Bezieht sie sich auf die swap() Technik?
-
Ich hatte das jetzt so verstanden, dass vector<> generell seinen Speicher nicht freigeben würde. Ich denke mal, dass ich das hier falsch verstanden habe.
-
FrEEzE2046 schrieb:
Ich hatte das jetzt so verstanden, dass vector<> generell seinen Speicher nicht freigeben würde. Ich denke mal, dass ich das hier falsch verstanden habe.
Doch, std::vector gibt sämtlichen allokierten Speicher am Ende seiner Lebenszeit wieder frei. Fallstricke wie Zeiger auf dynamisch erzeugte Objekte, deren Adressen in std::vector verwaltet werden gibt es natürlich, aber solange man "vollständige" Objekte im Vektor ablegt treten keine memory leaks auf.
-
FrEEzE2046 schrieb:
pumuckl schrieb:
Das hilft IIRC auch nicht, sondern leert auch nur v. Der behält seinen Speicher trotzdem bein. Wirklich gelöscht wirds durch swap:
std::vector<int> v; // fülle v v.swap(std::vector<int>())Das war mir auch noch nicht bekannt. Gibt vector den allokierten Speicher nicht im Destruktor wieder frei?
Doch, und zwar nur im Destruktor. Im gezeigten Code wird aber nur der temporäre leere vector zerstört, der vector v behält seinen Speicher. Der op= von std::vector arbeitet wohlgemerkt nicht mit copy&swap - das liegt an der "don't pay for what you don't use"-Philosophie von C++, die verbietet, für einen exceptionsicheren op= einen temporären vector von potentiell mehreren MB Größe anzulegen.