Discussion:
Free und FreeAndNil
(zu alt für eine Antwort)
Jens Kallup
2022-04-12 09:13:41 UTC
Permalink
Hallo,

in Àlteren Versionen von Delphi hatte ich immer im dtor
Free benutzt, um ein Objekt bzw. die Referenz darauf zu
löschen bzw. den belegten Speicher durch das OS wieder
freizugeben.

Allerdings kommen nun neuere Versionen (so ab Version 5)
mit der Funktion FreeAndNil daher.

Was ist an dieser Funktion anders als an Free ?

In Àlteren Quellcodes hatte ich fast nie folgende zwei-
liner verwendet:

obj.Free;
obj := nil;

Ich nehme mal an das FreeAndNil das gleiche macht.
Alllerdings wÃŒrde es mich mal interessieren, ob man denn
in den Àlteren Versionen tatsÀchlich von "obj := nil;"
abhÀngig war ?

Weil, in neueren Version (ich verwende gerade Delphi 7)
es dazu fÃŒhren kann, das man zwar den Speicher mit .Free
freigibt, aber der Zeiger auf das Objekt zeigt oder gar
manchmal auf eine andere Adresse im Speicher, wie ich das
so auch schon feststellen konnte.

Erst durch die Verwendung von FreeAndNil kann ich sicher
sein, das ich mit:

if obj = nil then obj := TObj.Create;

a) abfragen kann, das "obj" tatsÀchlich "null" ist, um
im Anschluß dann
b) das "obj" mit Create neu erstellen kann, sofern es dann
gebraucht wird.

Mit freundlichen GrÌßen

Jens Kallup
Holger Schieferdecker
2022-04-13 07:04:16 UTC
Permalink
Post by Jens Kallup
Hallo,
in älteren Versionen von Delphi hatte ich immer im dtor
Free benutzt, um ein Objekt bzw. die Referenz darauf zu
löschen bzw. den belegten Speicher durch das OS wieder
freizugeben.
Allerdings kommen nun neuere Versionen (so ab Version 5)
mit der Funktion FreeAndNil daher.
Was ist an dieser Funktion anders als an Free ?
Na, wie es der Name schon sagt. :-)
Free gibt lediglich den Speicher frei und löscht das Objekt, aber die
Variable enthält immer noch den Pointer auf die Stelle, an der es mal im
Speicher war. Damit kann es (wie Du auch gemerkt hast) zu Problemen
kommen, wenn danach eine Funktion auf das Objekt zugreifen will.

FreeAndNil setzt zudem den Pointer noch auf NIL, damit wird das
umgangen, und Du kannst vor der Verwendung prüfen, ob das Objekt
wirklich existiert.
Post by Jens Kallup
In älteren Quellcodes hatte ich fast nie folgende zwei-
obj.Free;
obj := nil; >
Ich nehme mal an das FreeAndNil das gleiche macht.
Jein, im Endergebnis schon, aber es macht es etwas anders:

procedure FreeAndNil(var Obj);
// from Delphi 5 source, not available in Delphi 4 and below
var P:TObject;
begin
P:=TObject(Obj);
TObject(Obj):=NIL; // clear the reference before destroying the Object
P.Free;
end;

Zunächst wird ein Hilfspointer angelegt, der auf das Objekt zeigt. Dann
wird der eigentliche Pointer auf NIL gesetzt und danach erst das Objekt
mittels des Hilfspointers freigegeben.

So wie Du es oben schreibst, könnte theoretisch zwischen den beiden
Zeilen auf das Objekt zugegriffen werden. Es wäre dann aber schon
freigegeben, der Pointer jedoch noch nicht auf NIL gesetzt. So wie es
FreeAndNil macht, kann das nicht passieren.
Post by Jens Kallup
Alllerdings würde es mich mal interessieren, ob man denn
in den älteren Versionen tatsächlich von "obj := nil;"
abhängig war ?
Wenn man nur Free aufruft, ist das Verhalten in alten und neueren
Versionen meines Erachtens gleich. Also ja, man war davon abhängig.

Holger

Loading...