C++ Pointer wieder freigeben

Gast #3138076
Lesenswert?

Hallo,

habe eine Frage bzgl. Pointer.

Muss man Pointer, welche ich im public wie folgt deklariert habe:
(Borland Builder)

public:    // Anwender-Deklarationen
TTime *time;

wieder freigeben bzw. löschen?

Hier deklariere ich:

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
time = new TTime();
...
.
}


Wenn ja wo muss ich die Zeile delete[] time; einfügen bzw. warum muss 
man diese wieder freigeben?

Danke für eure Hilfe!

SG Wolfi
Gast #3138084
Lesenswert?

Wolfi schrieb:
> Wenn ja wo muss ich die Zeile delete[] time; einfügen bzw. warum muss
> man diese wieder freigeben?
Den Pointer musst du nicht explizit wieder freigeben. Allerdings muss du 
das ZIEL, auf das der Pointer zeigt, wieder freigeben. Das machst du 
dann, wenn du das Ziel nicht mehr brauchst. Dazu verwendest du "delete" 
und nicht "delete []", da du TTime ja auch mit "new" und nicht "new 
[...]" angelegt hast. Falls du willst dass dein TTime Objekt genau so 
lange existiert wie deine TForm1-Klasse, kannst du einfach "TTime time;" 
schreiben, und new/delete komplett weglassen. Lies ein C++ Buch, da ist 
alles erklärt.
PS: Borland C++ Builder ist uralt. Verwende was moderneres wie GCC oder 
wenns sein muss Visual Studio.
#3138106
Lesenswert?

Wolfi schrieb:
> Kannst ich noch eine kurze Erklärung bekommen, warum man beim Ziel den
> Pointer wieder freigeben muss?

Weil sonst jedesmal, wenn ein TForm1 Objekt erzeugt wird, auch ein TTime 
Objekt neu erzeugt wird. Gibst du das Objekt nicht frei, dann belegt es 
Speicher. Nach 3 Milliarden derartiger Objekte, die im Speicher 
rumlungern, hat der PC dann keinen Speicher mehr, weil alles mit nicht 
mehr gebrauchten TTime-Objekt-Leichen aufgebraucht wurde.

Du räumst ja auch hinter dir auf, wenn du etwas nicht mehr brauchst. 
Oder nicht?
Gast #3138133
Lesenswert?

BTW, C++ ist nicht Java!
Dort wird jedes Objekt mit new erzeugt.
C++ kann Objekte auch quasi "inline" erzeugen, d.h. als globale oder 
lokale Variable von Typ einer Klasse. Wird das Objekt zur Laufzeit 
sichtbar, dann wird es "konstru(kt)iert". Verschwindet die lokale 
Variante wieder aus der Sichtbarkeit, dann wird automatisch 
"destru(kt)iert".
Komplizierter als Java, aber komfortabel.
Gast #3138162
Lesenswert?

Dr. Sommer schrieb:
> PS: Borland C++ Builder ist uralt. Verwende was moderneres wie GCC oder
> wenns sein muss Visual Studio.

C ist ja noch älter muss ich jetzt F# oder irgendsowas verwenden ;-)
Der 2006er CBuilder den ich privat verwende ist was das Handling und die 
Doku  angeht dem 2012er Visual Studio zu dem man mich mit Geld zwingt 
immer noch haushoch überlegen.

Karl Heinz Buchegger schrieb:
>> Kannst ich noch eine kurze Erklärung bekommen, warum man beim Ziel den
>> Pointer wieder freigeben muss?

> Weil sonst jedesmal, wenn ein TForm1 Objekt erzeugt wird, auch ein TTime
> Objekt neu erzeugt wird. Gibst du das Objekt nicht frei, dann belegt es
> Speicher. Nach 3 Milliarden derartiger Objekte, die im Speicher
> rumlungern, hat der PC dann keinen Speicher mehr, weil alles mit nicht
> mehr gebrauchten TTime-Objekt-Leichen aufgebraucht wurde.

Na ja ganz so wild isses dann doch nicht. Wenn das System mitbekommt das 
die Anwendung endet wird der gesamte reale Speicher der im Adressraum 
der Anwendung gemappt war feigegeben, ebenso alle benutzten Handles. 
Jedenfalls theoretisch praktisch klappt das mit den Handles nicht so 
gut.

Peter II schrieb:
> malloc gehört ein free
> und zu jedem
> new gehört ein delete

Wobei das sicher die bessere Methode ist!

Stefan
#3138319
Lesenswert?

Wolfi schrieb:
> also bedeutet das bei jedem Zyklus bzw neu Durchlauf würde dann ein
> neues TTime erzeugen und irgendwann ist der Arbeitsspeicher voll?

Ja.

> Muss man nur bei Pointern das Objekt wieder löschen oder gibt es andere
> Typen auch noch bei denen man das beachten muss?

Das hat erstmal nur indirekt mit Pointern zu tun. Nicht alles, worauf 
ein Pointer zeigen kann, muß freigegeben werden. Peter hat's gut 
zusammengefasst. Was mit new erstellt wurde (und nur das), muß mit 
delete wieder freigegeben werden.
Die nächste Frage ist, wie schon angedeutet wurde, ob du überhaupt new 
brauchst. Prinzipiell gibt es in C++ drei Arten, wie Objekte angelegt 
werden können, nämlich statisch, automatisch und dynamisch.
Statische Objekte existieren, bis das Programm beendet wird und werden 
dann automatisch wieder freigegeben. Globale Variablen und lokale als 
"static" deklariert Variablen gehören zu dieser Art.
Automatische Objekte sind solche, die in Funktionen als nicht-statische 
lokale Variablen oder Parameter definiert sind. Die werden automatisch 
wieder freigegeben, wenn der Codeblock, in dem sie definiert sind, 
verlassen wird.
Und dann gibt es noch dynamische Objekte. Die werden mit new erzeugt und 
existieren so lange, bis man sie explizit wieder freigibt. Dort hat man 
die volle Kontrolle über die Lebensdauer des Objekts, aber auch die 
Verantwortung, sie wieder aufzuräumen.
Gast #3155545
Lesenswert?

Rolf Magnus schrieb:
> Und dann gibt es noch dynamische Objekte. Die werden mit new erzeugt und
> existieren so lange, bis man sie explizit wieder freigibt. Dort hat man
> die volle Kontrolle über die Lebensdauer des Objekts, aber auch die
> Verantwortung, sie wieder aufzuräumen.

Oder man benutzt Smart Pointer: http://en.cppreference.com/w/cpp/memory
Dann braucht man sich um das Aufräumen nicht mehr zu kümmern. ;-)

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