Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Warum FreeAndNil so umständlich? (https://www.delphipraxis.net/88538-warum-freeandnil-so-umstaendlich.html)

Cöster 16. Mär 2007 22:43


Warum FreeAndNil so umständlich?
 
Hi!

Bei der Implementierung von FreeAndNil hätte ich eigentlich erwartet:

Delphi-Quellcode:
procedure FreeAndNil(var Obj);
begin
  Obj.Free;
  Obj := nil;
end;
Allerdings ist es etwas umständlicher implementiert:

Delphi-Quellcode:
procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;
Könnt ihr mir sagen, warum?

Gruber_Hans_12345 16. Mär 2007 23:02

Re: Warum FreeAndNil so umständlich?
 
ohne eine ahnung zu haben, würde ich mal drauf tippen : damit der übergebene Pointer auf nil gesetzt wirde, selbst wenn im Destroy des Objektes eine Exception auftritt, und damit das FreeAndNil unterbrochen wird

sakura 16. Mär 2007 23:06

Re: Warum FreeAndNil so umständlich?
 
Zitat:

Zitat von Gruber_Hans_12345
ohne eine ahnung zu haben, würde ich mal drauf tippen : damit der übergebene Pointer auf nil gesetzt wirde, selbst wenn im Destroy des Objektes eine Exception auftritt, und damit das FreeAndNil unterbrochen wird

100% korrekt!

...:cat:...

MStoll 17. Mär 2007 01:58

Re: Warum FreeAndNil so umständlich?
 
Hi

nur ma ne Frage am Rande dazu. Wäre es langsamer, es stattdessen mit nem try..finally-Konstrukt zu versuchen? Find ich irgendwie eleganter...

Gruß
Michael

omata 17. Mär 2007 02:05

Re: Warum FreeAndNil so umständlich?
 
Wieso try-finally :gruebel: Meinst du vielleicht try-except :?:

Verwirrte Grüsse
Thorsten

Kedariodakon 17. Mär 2007 02:06

Re: Warum FreeAndNil so umständlich?
 
Ich denke nicht =p
Das ist so schon die schnellste Variante, würd ich behaupten..

Bye Christian

himitsu 17. Mär 2007 02:44

Re: Warum FreeAndNil so umständlich?
 
Delphi-Quellcode:
procedure FreeAndNil(var Obj);
begin
  try
    Obj.Free;
  finally
    Pointer(Obj) := nil;
  end;
end;
und ja, try-finaly wäre für diese Prozedur angebracht.
try-except würde die Exception abfangen und genau dieses soll nicht in dier Prozedur erfolgen.


was try-finally in etwa machen würde (als grobes Schema):
Delphi-Quellcode:
procedure FreeAndNil(var Obj);
begin
  ExceptionHandler.Installieren; // if Exception then goto doExcept;
  Obj.Free;
  goto doFinally;

  doExcept:
  ExceptionHandler.StackWiederherstellen;
  goto doFinally;

  doFinally:
  ExceptionHandler.Freigeben;
  Pointer(Obj) := nil;
end;

Luckie 17. Mär 2007 03:22

Re: Warum FreeAndNil so umständlich?
 
Warum sollte Free eine Exception auslösen? Dies könnte nur passieren, wenn das Objekt nil ist, aber das überprüft Free vorher.

himitsu 17. Mär 2007 04:24

Re: Warum FreeAndNil so umständlich?
 
Free ruft Destroy auf und darin kann ja wohl Unterumständen was passieren.

Kedariodakon 17. Mär 2007 04:27

Re: Warum FreeAndNil so umständlich?
 
Wenn im Destructor eine Exception passiert, passiert die, auch bei free...

Und dann wär die Variable nicht nil..
so wird sie erst auf nil gesetzt und dann das eigendliche Object zerstört...


Bye Christian

negaH 17. Mär 2007 10:59

Re: Warum FreeAndNil so umständlich?
 
ein try finally Block ist absolut überflüssig.

Was will der Code erreichen ?

Er will sicherstellen das die Referenz auf das Object -> Variable, in jedem Falle auf nil gesetzt wird.
Tja, und dies tut der Borlandcode perfekt.

In EAX ein Zeiger auf die Variable. In EDX wird das Object geladen, dann indirekt über [EAX] die Variable auf nil = 0 gesetzt und dann das Object in EDX zerstört. Effektiv benötigt damit FreeAndNil() maximal 5 Assemblerinstruktionen.

Vergleich mit try finally Block:

Wir können mit desem maximal exakt die gleiche Funktionalität erreichen wie ohne dem try finally block. Dafür wäre diese Methode, selbst wenn keine Exceptions auftreten, wesentlich langsammer. Ja sogar störanfälliger ;) Denn jeden CPU Takt länger den man benötigt um irgendwas zu machen, erhöht das Risiko das andere asynchrone Programmteile (IRQs zb. etc.pp) irgendwelche Informationen zerstören können.

Die Lösung von Borland ist damit perfekt und weitaus besser als ein try finally Block.

Gruß Hagen

sakura 17. Mär 2007 11:03

Re: Warum FreeAndNil so umständlich?
 
Zitat:

Zitat von Luckie
Warum sollte Free eine Exception auslösen? Dies könnte nur passieren, wenn das Objekt nil ist, aber das überprüft Free vorher.

Wenn das Objekt bereits entladen (Free, Destroy) wurde und nicht auf NIL gesetzt wurde, dann wird man recht schnell mit einer Exception begrüßt ;)

...:cat:...


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz