Destruktor - wann und wie wird Speicher freigegeben?

Gast #3078231
Lesenswert?

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 :) !
#3078300
Lesenswert?

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
#3079751
Lesenswert?

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.
#3079984
Lesenswert?

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.
Gast #3080315
Lesenswert?

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
#3080442
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren