multidim stl vector memory leak



  • 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.


Anmelden zum Antworten