Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Free und FreeAndNil

4 views
Skip to first unread message

Jens Kallup

unread,
Apr 12, 2022, 5:13:43 AM4/12/22
to
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
kallup_jens.vcf

Holger Schieferdecker

unread,
Apr 13, 2022, 3:09:15 AM4/13/22
to
Am 12.04.2022 um 11:13 schrieb 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.

> In älteren Quellcodes hatte ich fast nie folgende zwei-
> liner verwendet:
>
> 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.

> 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
0 new messages