Memory Leak with Pointer in Loop.

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
sacrif
Beiträge: 40
Registriert: 22. Januar 2010 18:52

Memory Leak with Pointer in Loop.

Beitrag von sacrif »

Hi, ich arbeite in visual studio 2008 und debugge mein Program gerade mit einem leak detector(visual leak detector). Dabei bekomme ich eine memory leak anzeige wenn ich code wie den folgenden schreibe:

Code: Alles auswählen

void MyClass::foo(double param1, double param2,...) // all params are int and doubles
{
	 vector<vector<Obj*>> objVectorStorage;
	  for(unsigned int i = 0; i < max1; i++) // max1 already given
	  {
		vector<Obj*> objVector;
		for(unsigned int j= 0; j < max2; j++) // max2 already given
		{
		  Obj* myobject = new Obj();
		  myobject->setData(param1, param2, ...); // all params are int and doubles
		  objVector.push_back(myobject);
		}
		objVectorStorage.push_back(objVector);
	  }

//do some calculations here then copy all data in one vector like shown in the following

  vector<Obj*> returnVecor;
  for(unsigned int i = 0; i < objVectorStorage.size(); i++)
  {
	  for(unsigned int j = 0; j < objVectorStorage[i].size(); j++)
	  {
		  Obj* tmpobj= objVectorStorage[i][j];
		  returnVecor.push_back(tmpobj);
	  }
  }
return returnVecor;
}
Das Memory leak wird für die Zeile "Obj* myobject = new Obj(); " in der inneren der ersten doppelten for loop angezeigt.

Mir ist zwar klar, dass der Obj pointer dann hier in der ersten doppelten for loop verloren geht, aber ich hab den pointer ja auch in den vector kopiert. Das sollte daher doch eigentlich kein leak sein oder? und es ändert auch nichts wenn ich am ende des inneren for myobject = NULL; setzte. VIelleich kann mir hier wer weiterhelfen wo dass Problem liegt.

Danke & lg scr
kater
Beiträge: 306
Registriert: 29. Dezember 2009 01:13
Wohnort: Darmstadt

Beitrag von kater »

Wie, wo, wann löschst du sie wieder? Mehr Code.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

der Vector entleert ja auch nur seinen Inhalt ... das heisst die Obj-pointer gehen verloren.
Das delete, was zu dem new dazugehoert, wird nie aufgerufen.
du muesstest den vctor bevor du ihn entleerst, durchlaufen und auf allen zeigern drinn das delete aufrufen !

Obj* myobject = new Obj();
myobject->setData(param1, param2, ...); // all params are int and doubles
vom design her auch eher unschoen:
warum das Obj dynamisch?
Grundregel: statisch(stack) wo du kannst, Heap/Freestore wo du musst.

Der vector schiebt dein Obj doch sowieso aufn Freestore.
Gruende um das trotzdem dynamisch zu machen waeren:
- Deine Kopien sind performancetechnisch sündhaft teuer
- Dein Obj passt einfach nimmer aufn Stack(zu gross).

new() zu vermeiden ist der natuerlichere Weg, memoryleaks zu vermeiden !

Ciao ..
sacrif
Beiträge: 40
Registriert: 22. Januar 2010 18:52

Beitrag von sacrif »

Hi, danke für eure antworten. Hab den Fehler inzwischen gefunden. Das problem war dass ich ursprünglich die pointer zu den objecte aus dem vector weiter verwendet hab - in einer erweiterung hab ich dann aber die objecte mehrmals duplizieren müssen und hab dann ganz vergessen dass es die originalen ja auch noch gibt - die sind dann ungenutzt stehen geblieben.

Wegen dynamischen object: die copien sind zwar nicht soooo performancelastig, aber müssen relativ oft durchgeführt werden (in manchen fällen wie oben erwähnt muss ich eh wirklich das object kopieren, aber oft genug tuts der pointer auch - daher is das eher für die performance).

Danke nochmals & lg scr
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Wegen dynamischen object: die copien sind zwar nicht soooo performancelastig, aber müssen relativ oft durchgeführt werden (in manchen fällen wie oben erwähnt muss ich eh wirklich das object kopieren, aber oft genug tuts der pointer auch - daher is das eher für die performance).
Noch 2 Anmerkungen:
Auch von "statisch" angelegten Objecten kannst Du genau so Zeiger weitergeben !
Du weisst dann, wenn du nen Zeiger hasst, hasst du "nur nen zusaetzlichen Verweis (Referenz)"
Bringt uns gleich zum naechsten Punkt -> die fertige dereferenzierte Form eines Zeigers ist die Referenz. Um kopien zu vermeiden sollte man unter c++ diese vorzugsweisse verwenden.

Falls du wirklich Heap Objecte brauchst, solltest Dir dann auch die Smartpointer mal anschauen.
In der STL gibts leider nur einen rudimentaeren, aber TR1(wenn verfügbar) und/oder die boost helfen da weiter.

Generell fuer c++:
Rohe Zeiger, Rohes new -> unschoen, wenig c++ like !
Gewoehnst man sich von haus aus die C++ Techniken an, hat man viel weniger Probs mit Memoryleaks.
Memoryleaks sind daher meist keine "Unaufmerksamkeit" mehr, sondern ein Design-Fehler ! Performance ist da keine Ausrede !
MemoryLeaks sind nur ein Punkt, einher mit dem Thema geht meist die Exceptionsicherheit / ExceptionNeutralitaet.

Ciao ...
Antworten