PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Speicher freigeben bei einem Vector



AnubisTheKing
08-08-2006, 13:12
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

Joghurt
09-08-2006, 19:20
Brauchst du wirklich einen vector<CMovement*>? Reicht nicht ein vector<CMovement>? In diesem Fall übernimmt vector das nämlich beim clear() für dich...

AnubisTheKing
09-08-2006, 21:08
Leider brauche ich einen vector<CMovement*>. Da komme ich lieder nicht drum rum.

Joghurt
09-08-2006, 23:15
www.valgrind.org

AnubisTheKing
15-08-2006, 08:07
Wenn du mir jetzt valgrind noch für Windows zeigst geht alles kar :-). Ist nämlich leider ein Windows Progamm.

locus vivendi
15-08-2006, 14:45
Wenn du mir jetzt valgrind noch für Windows zeigst geht alles kar :-). Ist nämlich leider ein Windows Progamm.
Wenn du ein vollständiges, lauffähiges Beispiel postest, könnte das evtl. auch jemand für dich machen. Ansonsten gibt es Leakchecker auch für Windows. Purify zum Beispiel. Oder du kannst den Gcc verwenden, dessen "mudflap" Debugging ebenfalls Lecks ausgeben kann (falls das auch unter Windows funktioniert). Die Microsoft IDE hat bestimmt auch ein Äquivalent. Schau dich einfach mal um, was es so gibt.

Ich sehe mindestens ein Problem in deinem Code, welches sich allerdings nicht in dem von dir beschriebenen Symptom manifestiert. Dieses Problem ist, dass manche Ressourcen nicht freigegeben werden, wenn später eine Ausnahme geworfen wird. Z.b. hält movementvec einen Zeiger auf eine mit new erzeugten vector. Später wird "new CPoint" ausgeführt. Das kann schiefgehen, es würde eine Ausnahme geworfen werden. Dadurch geht der vector verloren.

Also zum Schluss nochmal: Poste ein komplettes Beispiel, dann kann man weitersehen.

anda_skoa
15-08-2006, 19:37
Bist du sicher daß die Objekte nicht gelöscht werden?

zB ein einfacher check mit einem static counter und Constructor/Destructor

D.h. im Constructor von CMovement einen static int erhöhen und im Desktruktor verringern.

Dann am Anfang der Funktion auslesen, die lokale Referenz bei Operation so inkrementieren/dekrementieren wie du es al richtiges Verhalten erwartest und dann am Ende bzw jederzeit mit dem static Counter vergleichen

Ciao,
_