Speicher freigeben bei einem Vector



  • hi,

    ich habe folgendes Problem. Ich habe eine Methode in der ein Vektor angelegt wird

    vector<CMovement*>* movementvec=new vector<CMovement*>
    

    Diesen fülle ich nun mit Elementen und tausche am Ende seinen Inhalt mit einem anderen Vektor vom gleichen Typ

    m_current_movement->swap(*movementvec);
    

    Danach möchte ich nun den Speicher, den movementvec nun belegt wieder freigeben. Ein einfaches clear() und delete auf den Vector reicht dabei ja nicht, da in dem Vektor Pointer gespeichert sind. Ich muss ja also erst die Elemente einzelnt mit einem delete löschen und kann danach ein clear() und ein delete auf den Vektor machen. Dafür habe ich mir folgende Template geschrieben:

    template<typename T>
    void CGCodeReader::DeleteVectorWithPointers(T* vec){
    	for(int i=0; i<vec->size();i++){
    		delete vec->at(i);
    		vec->at(i)=NULL;
    	}
    	vec->clear();
    	delete vec;
    }
    

    Diese Funktion scheint auch ordentlich zu funktionieren, jeden Falls wird an allen anderen Stellen in meinem Projekt der Speicher wieder ordentlich frei gegeben. Nur eine Funktion habe ich, bei der ich es einfach nicht schaffe, den vom Vektor belegten Speicher wieder ordentlich freizugeben. Vielleicht hat einer von euch ja eine Idee woran das liegt. Hier die gekürtze Funktion:

    int CGCodeReader::convertToMovements(std::vector<CNcSatz*>* ncliste, bool original)
    {
    	if(ncliste==NULL && !original) ncliste = m_current_ncsatzliste;
    	else if(ncliste==NULL && original) ncliste = m_original_ncsatzliste;
    
    	vector<CMovement*>* movementvec=new vector<CMovement*>;
    //CAxes *Axes = new CAxes(0,0,0);  //! \todo: define kinematic and create get set functions 
    
    	//remeber the last point we visited (first one ist the startpoint)
    	CPoint3 *lastpoint = new CPoint3();
    	lastpoint->SetX(STARTX);
    	lastpoint->SetY(STARTY);
    	lastpoint->SetZ(STARTZ);
    
    	//now walk through all entries (NCSatz)
    	vector<CNcSatz*>::iterator iterncsatz;
    	iterncsatz=ncliste->begin();
    	int tmp = 0;
    	int GCommand = -1;
    	while(iterncsatz!=ncliste->end()){
    		GCommand = getCurrentGCommand(*iterncsatz);
    		if (GCommand==1 || GCommand==0)
    		{
    			//we will create a movement from the last point and the next point
    			CMovement* movement = new CMovement(linear);
    
    [... (hier wird das movement Objekt mit den richtigen Daten gefüllt)]
    
    		movementvec->push_back(movement);
    
    		}//if (GCommand==1)
    
    		iterncsatz++;
    		tmp++;
    	}//while(iterncsatz!=ncliste->end())
    
    	//delete Axes;
    	delete lastpoint;
    
    	if(!original) m_current_movement->swap(*movementvec);
    	else m_original_movement->swap(*movementvec);
    
    	DeleteVectorWithPointers(movementvec);
    
    	return 1;
    }
    

    Also nach DeleteVectorWithPointers(movementvec) belegt mein Programm immernoch so viel Speicher wie vorher. Pro druchlauf der Funktion erhöht sich der Speicherbrauch bei mir um ca. 20 MB, da die Datensätze die bearbeitet werden sehr groß sind.

    Wäre für jede Idee, warum der Speicher nicht ordentlich freigegeben wird dankbar.

    Grüße
    AnubisTheKing



  • Weiss nicht ob das das Problem ist, aber du übergibst der template Funktion keine Parameter?

    DeleteVectorWithPointers(movementvec);
    
    DeleteVectorWithPointers< vector< CMovement* > >(movementvec);
    


  • template<typename T>
    void CGCodeReader::DeleteVectorWithPointers(T* vec)
    {
        for(typename T::iterator i = vec.begin (); i != vec->end(); ++i)
            delete *i;
        delete vec;
    }
    

    Die sollte es auch tun.

    1310-Logik schrieb:

    Weiss nicht ob das das Problem ist, aber du übergibst der template Funktion keine Parameter?

    DeleteVectorWithPointers(movementvec);
    
    DeleteVectorWithPointers< vector< CMovement* > >(movementvec);
    

    Das bekommt der Compiler schon selbst hin, sonst beschwert er sich.

    Springt er auch tatsächlich in die for-Schleife hinein?



  • DeleteVectorWithPointers< vector< CMovement* > >(movementvec);
    

    Habe das gerade mal getestet, ändert leider nichts an meinem Problem. Der Speicher wird einfach nicht frei gegeben.

    Mit

    < vector< CMovement* > >
    

    gibst du den Typ für das Template an oder? Muss man das machen oder ist das optional? Kompiliert ja auch ohne die Angabe.



  • .filmor schrieb:

    Das bekommt der Compiler schon selbst hin, sonst beschwert er sich.

    Sry, wusst ich nicht.



  • 1310-Logik schrieb:

    .filmor schrieb:

    Das bekommt der Compiler schon selbst hin, sonst beschwert er sich.

    Sry, wusst ich nicht.

    Hast du dich noch nie gefragt, wieso die <algorithm>-Funktionen mit jedem (passenden) Container funktionieren? 😉



  • .filmor schrieb:

    1310-Logik schrieb:

    .filmor schrieb:

    Das bekommt der Compiler schon selbst hin, sonst beschwert er sich.

    Sry, wusst ich nicht.

    Hast du dich noch nie gefragt, wieso die <algorithm>-Funktionen mit jedem (passenden) Container funktionieren? 😉

    Ehrlich gesagt, nein, solange sie funktionieren 🙂



  • @.filmor

    Also der springt in die for-schleife rein. Das delete wird auch ausgeführt und wenn man sich den Speicherinhalt im Debug Modus anschaut, dann sieht man zwar, dass der Inhalt von den CMovement* Objekten gelöscht wird, aber der Speicher nimmt nicht ab.

    Gute Idee einen Iterator zum durchlaufen zu benutzen. Werde ich bei mir mal so einbauen. Nur leider ändert das nichts meinem Speicherproblem.



  • AnubisTheKing schrieb:

    if(!original) m_current_movement->swap(*movementvec);
    	else m_original_movement->swap(*movementvec);
    
    	DeleteVectorWithPointers(movementvec);
    

    allokierst du m_current_movement bzw. m_original_movement irgendwo, und wenn ja, gibst du die wieder frei?



  • m_current_movement und m_original_movement werden woanders angelegt. Der Speicher von denen wird beim Beenden des Programms im Destruktor über die gleiche Templatefunktion freigegeben. Ansonsten wird m_current_movement und m_original_movement nur in dieser Funktion geändert.


Log in to reply