Hallo Community, ich habe vorher nur mit Java zu tun gehabt, deshalb verwirrt mich die manuelle Speicherfreigabe / Objektlöschung noch ein bisschen. Ich habe mir eine kleine Test-Klasse geschrieben. Am Ende kann ich sehen, dass der Destruktor aufgerufen wurde. Die frage die ich mir jetzt stelle - reicht das? Weil ich immer wieder in Online-Quelltexten sehe, dass im Destruktor noch mit delete gearbeitet wird. Muss ich die ganzen angelegten varaiblen innerhalb eines Objektes noch mit delete löschen lassen, bevor dann die Referenu auf das Objekt durch den Destruktor gelöscht wird? Viele Grüße :) !
Lars w. schrieb: > Muss ich die ganzen > angelegten varaiblen innerhalb eines Objektes noch mit delete löschen > lassen, Wenn die Variablen jeweils mit new angelegt wurden, ja. Zu jedem new gehört ein korrespondierendes delete.
Wenn du Member mit new erzeugst, musst du sie im Destruktor mit delete zerstoeren. Fuer solche mit new[] wird delete[] genommen. Fuer malloc oder calloc wird free() genommen.
Wie immer kann ich hier raten: Schau' dir mal an, was valgrind zu deinem Programm sagt. Das ist immer sehr interessant -- in Fall von Memory Leaks hast du was falsch gemacht, wenn am Schluss nicht "definitely lost: 0" da steht. ;) Grüße, Sven
Vielen Dank euch ! Leuchtet alles ein. Und valgrind klingt super - kennt da jemand was äquivalentes zu Windows?
Valgrind für Windows ist in Arbeit, scheint aber noch sehr frisch zu sein: http://sourceforge.net/projects/valgrind4win/ Hier sind ein paar Vorschläge für Ersatzlösungen: http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows
VIelen Dank ! Ich hab mir jetzt Dr.Memory geladen. Dadurch konnte ich schon 2 Speicherleaks in meinem Programm beheben (eben Aufgrund des vergessenen Deletes bei dynamisch angelegten Speicher per new...). Ich bin total begeistert ^^
Oft ist auch manuelles Speichermanagement in C++ nicht ideal. Das lohnt sich nur in manchen Fällen. Es gibt noch weitere Möglichkeiten: * shared pointer -- macht reference counting. Das hat natürlich einen gewissen Overhead, ist aber in vielen Fällen egal. Dafür garantiert diese Methode, dass das Objekt gelöscht wird, genau dann wenn es nirgends mehr benutzt wird. * scoped pointer -- wenn man Objekte nur mit "new" anlegt, weil sie zu groß sind für den Stack, ist das die richtige Methode * memory pools -- wenn man viele kleine Allokationen braucht, die alle gemeinsam wieder freigegeben werden sollen, ist das oft auch eine gute Idee. Die stdlib hat diverse pointer-Klassen für sowas. Grüße, Sven
Danke dir Sven, auch das werde ich mir anschauen :) Lg
Und dann ist natürlich noch zu erwähnen, daß man Objekte oft gar nicht mit new anlegen muß. Wenn man aus der Java-Ecke kommt, ist das ja nicht selbstverständlich. Es gibt in C++ drei Arten von Speicher, nämlich statisch, dynamisch und automatisch, und Instanzen jedes Datentyps können auf jede dieser drei Arten erzeugt werden, egal ob es sich um Klassen oder eingebaute Typen handelt. Dabei leben "statische" Objekte bis zum Programm-Ende und werden dann zerstört, "automatische" Objekte sind lokale Variablen, die beim Verlassen des Blocks, in dem sie definiert sind, zerstört werden, und "dynamische" Objekte sind die, die mit new angelegt wurden. Diese (und nur die) müssen mit delete explizit zerstört werden.
Rolf Magnus schrieb: > Und dann ist natürlich noch zu erwähnen, daß man Objekte oft gar nicht > mit new anlegen muß. Wenn man aus der Java-Ecke kommt Rolf hat absolut recht. Gerade die Leute aus der Java oder C# Ecke tendieren dazu, viel zu viel mittels new anzulegen, weil sie das von Java/C# so gewohnt sind. Dabei muss man in C++ viel weniger mittels new allokieren und wenn tatsächlich mal etwas dynamisch allikiert werden muss, dann ist man mit den Containern der STL oft (aber nicht immer) besser bedient. Und auch immer an die 'Rule of three' denken: Benötigt man unbedingt eine der 3 Funktionen Destruktor, Copy Constructor oder Assignment-Operator, dann benötigt man meistens alle 3. Macht man selbst dynamisches Memory Management, dann benötigt man auf jeden Fall alle 3. Selbst wenn 2 davon (CCtor und Op=) lediglich so trivial verpackt werden, dass sie für Compiler/Linker nicht benutzbar sind und daher jeder Versuch sie einzusetzen zu einem Compiler/Linker Fehler führt, der Schlimmeres zur Laufzeit verhindert.
Hallo Karl Heinz, Karl Heinz Buchegger schrieb: > Dabei > muss man in C++ viel weniger mittels new allokieren und wenn tatsächlich > mal etwas dynamisch allikiert werden muss, dann ist man mit den > Containern der STL oft (aber nicht immer) besser bedient. Ich tendiere eher umgekehrt: Sie sollten alle nicht-Primitive mit new/(boost::)shared_ptr anlegen (soweit möglich)... > Macht man selbst dynamisches Memory Management, dann benötigt man auf > jeden Fall alle 3. Selbst wenn 2 davon (CCtor und Op=) lediglich so > trivial verpackt werden, dass sie für Compiler/Linker nicht benutzbar ...genau, c'ctor und op= lediglich deklarieren um deren (versehentliche) Nutzung auszuschließen. Das hat den Vorteil, sie können "normal" weiter programmieren wie bisher und die (meist) unnötigen (und manchmal auch fehlerhaften) Objektkopien entfallen. Vor einer op= Zuweisung in C++ wird imho viel weniger nachgedacht als vor einem copy/clone. Grüße, Steffen
Steffen schrieb: > Hallo Karl Heinz, > > Karl Heinz Buchegger schrieb: >> Dabei >> muss man in C++ viel weniger mittels new allokieren und wenn tatsächlich >> mal etwas dynamisch allikiert werden muss, dann ist man mit den >> Containern der STL oft (aber nicht immer) besser bedient. > > Ich tendiere eher umgekehrt: Sie sollten alle nicht-Primitive mit > new/(boost::)shared_ptr anlegen (soweit möglich)... Sofern eine dynamische Allokierung überhaupt notwendig ist - das ist der springende Punkt auf den ich raus will.
Hallo nochmal, vielen Dank für die weiteren Hinweise, ich denke, ich habe es jetz verstanden. Ich versuche auch möglichst nicht mi new* o.ä zu arbeiten. Allerdings benötige ich für ein kleines Spiel ein dynamisches Array, daher bin ich darauf gekommen.
Lars w. schrieb: > Hallo nochmal, > > vielen Dank für die weiteren Hinweise, ich denke, ich habe es jetz > verstanden. Ich versuche auch möglichst nicht mi new* o.ä zu arbeiten. > Allerdings benötige ich für ein kleines Spiel ein dynamisches Array, > daher bin ich darauf gekommen. std::vector ist dein Freund.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.