Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi free oder freeAndNil() (https://www.delphipraxis.net/43274-free-oder-freeandnil.html)

Gambit 31. Mär 2005 21:08


free oder freeAndNil()
 
Hallo,

wann ist welche von den beiden folgenden Implementierungen besser?

Delphi-Quellcode:
var
  myList : TList;

begin
  myList := TList.Create;
  ...
  myList.free;
end;
Delphi-Quellcode:
var
  myList : TList;

begin
  myList := TList.Create;
  ...
  FreeAndNil(myList);
end;
Ich habe da immer noch Probleme, wie ich ein Objekt am besten deinstanziere, so dass wirklich nichts mehr schiefgehen kann...

Gruß

Gambit

jfheins 31. Mär 2005 21:10

Re: free oder freeAndNil()
 
Dann mach es so:
Delphi-Quellcode:
var
  myList : TList;

begin
try
  myList := TList.Create;
  ...
finally
  FreeAndNil(myList);
end;
end;
Wenn dus danach nicht mehr brauchst, kannst du auch free nehmen, der einzige Unterschied ist, dass du dann nicht mit Assign() prüfen kannnst ...

bttb930 31. Mär 2005 21:32

Re: free oder freeAndNil()
 
Eigentlich ganz simpel:

Free gibt den Speicherplatz frei, setzt aber nicht den Zeiger auf diesen Speicherbereich auf nil. Das heißt der Zeiger hängt hinterher und zeigt ins Nirvana.

FreeAndNil gibt den Speicherplatz frei und setzt hinterher den Zeiger auf nil.

Erstere Methode:

MyList ist ja nicht anderes als ein Zeiger, der auf den Speicherbereich zeigt, wo MyList seine Daten liegen hat. MyList.Free gibt diesen Speicherbereich frei, aber MyList zeigt nach wie vor in die Richtung. Würde man hinterher MyList.Add machen, würde das einen Crash verursachen.

Zweitere:

FreeAndNil(MyList) gibt den Speicherbereich frei und setzt MyList auf Nil. MyList.Add verursacht nach wie vor einen Crash, aber man kann if Assigned(MyList) then MyList.Add aufrufen, was im ersteren Fall (nur Free) auch zum Crash führt, im zweiteren aber nicht.

Fazit: FreeAndNil rufst Du immer dann auf, wenn Du mit der freizugebenden Variablen weiter arbeiten willst. Free alleine reicht, wenn Du das nicht vor hast (z.B. kann man am Ende einer Prozedur die lokalen Variablen per Free frei geben, ebenso im Destruktor einer Klasse die Klassenfelder, in jeder anderen Klassenmethode würde man zur Freigabe von Klassenfelder eher FreeAndNil verwenden).

Grundsätzlich gilt: Wenn Du dir nicht sicher bist, dann verwende lieber FreeAndNil. Damit machst Du nichts falsch.

Gambit 31. Mär 2005 21:34

Re: free oder freeAndNil()
 
Zitat:

Zitat von jfheins
Wenn dus danach nicht mehr brauchst, kannst du auúch free nehmen, der einzige Unterschied ist, dass du dann nicht mit Assign() prüfen kannnst ...

Und was heißt denn nun, "wenn dus nicht mehr brauchst..."? Ich meine, wenn ich das Objekt(also aList) wieder brauche, muss ich es doch eh neu instanzieren, oder nicht - egal ob ich aList.free oder freeAndNil(aList) benutze.

Pseudemys Nelsoni 31. Mär 2005 21:38

Re: free oder freeAndNil()
 
Es könnte aber sein das du dein Create von einer if bedingung abhängig machst, z.b so:

Delphi-Quellcode:
FreeAndNil(List);
if bla then
  List := TList.Create;
if Assigned(List) then....
Das soll nur ein Beispiel sein, da man auch nach der bla abfrage nen begin, end block benutzen könnte..
Wie gesagt...nur ein Beispiel^^

jfheins 31. Mär 2005 21:40

Re: free oder freeAndNil()
 
Zitat:

Zitat von Gambit
Zitat:

Zitat von jfheins
Wenn dus danach nicht mehr brauchst, kannst du auúch free nehmen, der einzige Unterschied ist, dass du dann nicht mit Assign() prüfen kannnst ...

Und was heißt denn nun, "wenn dus nicht mehr brauchst..."? Ich meine, wenn ich das Objekt(also aList) wieder brauche, muss ich es doch eh neu instanzieren, oder nicht - egal ob ich aList.free oder freeAndNil(aList) benutze.

Ja schon, aber falls es sein könnte, dass noch irgendwer darauf zugreifen will :arrow: FreeAndNil (z.B. bei globalen Objekten oder Klassenfeldern)
Eine lopkale Variable würde ich meistens mir .Free freigeben, da man dise meist nur einmal braucht, dann benutzt, und am Ende freigibt, kann es auch nicht sein, dass du nochmal drauf zugreifst.

Der einzige Unterschied ist halt, dass du per Assign() prüfen kannst, ob das Objekt existiert. (Was unsinnig ist, wenn du's eh nicht mehr brauchst)

Gambit 31. Mär 2005 21:43

Re: free oder freeAndNil()
 
@btb930: da warst du schneller, ich glaube(hoffe) jetzt hab ichs begriffen...

in deinem Beispiel würde ich, nachdem ich irgendwann mit freeAndNil(aList) freigegeben hätte, vor einem Aufruf von aList.add() mit assigned(aList) prüfen und wenn nicht assigned(aList) den Konstruktor wieder aufrufen bevor ich mit aList.add() weitermache?

Christian Seehase 31. Mär 2005 22:08

Re: free oder freeAndNil()
 
Moin Julius,

Deine Idee mit dem try/finally-Block als Resourcenschutzblock war zwar gut und richtig, hatte im gezeigten Beispiel eine kleine Macke:
try kommt bei try/finally nach dem Create, denn wenn Create schon fehlschlägt, hat man im finally-Abschnitt auch nichts freizugeben.

Allgemein:
Code:
<Resource belegen>
[b]try[/b]
  <Mit der Resource arbeiten>
[b]finally[/b]
  <Resource freigeben>
[b]end;[/b]
Das ist jetzt Ansichtssache, aber ich gebe immer mit FreeAndNil frei, damit ich nicht an entscheidender Stelle mal das Falsche verwende.
Da ich mir das als Quelltextvorlage abgelegt habe ist es auch nicht mehr Tipparbeit ;-)

choose 1. Apr 2005 08:53

Re: free oder freeAndNil()
 
Hallo Gambit,
vielleicht hilft der Beitrag FreeAndNil vs TObject.free weiter.

Gambit 1. Apr 2005 09:24

Re: free oder freeAndNil()
 
Ja, war hilfreich, Danke!

Gruß

Gambit


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:36 Uhr.

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