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
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.
Wolfi schrieb:> Kannst ich noch eine kurze Erklärung bekommen, warum man beim Ziel den> Pointer wieder freigeben muss?
weil man das Objekt nicht mehr braucht und man den Speicher zurückhaben
will.
Wenn die Variable time (in Klasse "A") der einzige Zeiger auf das auf
dem heap angelegte Objekt vom Typ TTime ist (also auch nur einem
einzigen Objekt der entsprechenden Klasse A zugewiesen wird) dann
sinnvollerweise im Destruktor von A. Ich würde, aber an Deiner Stelle
nochmal über das Design nachdenken.
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?
also bedeutet das bei jedem Zyklus bzw neu Durchlauf würde dann ein
neues TTime erzeugen und irgendwann ist der Arbeitsspeicher voll?
Muss man nur bei Pointern das Objekt wieder löschen oder gibt es andere
Typen auch noch bei denen man das beachten muss?
Vielen Dank für eure Hilfe nochmals!
Wolfi schrieb:> Muss man nur bei Pointern das Objekt wieder löschen oder gibt es andere> Typen auch noch bei denen man das beachten muss?
zu jeden
malloc gehört ein free
und zu jedem
new gehört ein delete
um was es sich dabei handelt ist egal.
Wolfi schrieb:> Muss man nur bei Pointern das Objekt wieder löschen oder gibt es andere> Typen auch noch bei denen man das beachten muss?
Auch ich rate dir ganz dringend zu einem ordentlichen C++ Buch.
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.
Wolfi schrieb:> Kannst du mir vl ein ordentliches C++ Buch empfehlen?
Ich hab damals mit dem Stroustrup C++ gelernt. Allerdings bin ich von
der C Schiene gekommen und ich habs im Original (also keine Übersetzung)
gelesen. Andere sagen wieder, der Stroustrup sei für Einsteiger nicht so
toll. Aber das ist, wie immer, Geschmackssache.
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
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.
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. ;-)