Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Funktion erstellt gibt Objekt zurück, wer räumt auf (https://www.delphipraxis.net/26004-funktion-erstellt-gibt-objekt-zurueck-wer-raeumt-auf.html)

Luckie 16. Jul 2004 11:21


Funktion erstellt gibt Objekt zurück, wer räumt auf
 
Ich habe eine Funktion, die als Ergebnis ein Objekt zurück gibt. Kann man sich so vorstellen:
Delphi-Quellcode:
function foo: TStrings;
begin
  result := TStringList.Create;
  ...;
  ...;

  result.Add('....');
  result.Add('....');
  result.Add('....');
end;
Aufruf:
Delphi-Quellcode:
Listbox1.Items := Foo;
Meine Frage: Ich weiß nicht, wo ich den Speicher wieder freigeben soll. :gruebel:

Nachtrag: Normaler weise mache ich so wa smit var Parametern, dann ist der Aufrufer dafür verantwortlich das Objkekt zu erstellen und wieder zu entsorgen, aber hier muss es als read Property eine Funktion sein.

Robert_G 16. Jul 2004 11:42

Re: Funktion erstellt gibt Objekt zurück, wer räumt auf
 
:gruebel:
Ist zwar irgendwie hässlich, sollte aber gehen. :roll:


Delphi-Quellcode:
var
  SL :TStrings;
begin
  try
    SL := foo();
    //Do something...
  finally
    if Assigned(SL) then
      Free(SL);
  end;
end;
noch ein Edit:
Sorgt die ListBox nicht von alleine für das Freigeben von TListBox.Items?
Da du Items das Ergebnis von foo übergibst, sollte das nicht dein Problem sein.

Delphi-Quellcode:
  ListBox.Items.Assign(foo());

supermuckl 16. Jul 2004 11:45

Re: Funktion erstellt gibt Objekt zurück, wer räumt auf
 
Delphi-Quellcode:
var
  SL :TStringList;
begin
  try
    SL := foo();
  finally
    if Assigned(SL) then
      Freeandnil(SL);
  end;
end;

Muetze1 16. Jul 2004 16:45

Re: Funktion erstellt gibt Objekt zurück, wer räumt auf
 
Moin!

Zitat:

Zitat von Robert_G
noch ein Edit:
Sorgt die ListBox nicht von alleine für das Freigeben von TListBox.Items?
Da du Items das Ergebnis von foo übergibst, sollte das nicht dein Problem sein.

Ist es aber doch: Die ListBox hat intern seine eigene Instanz (öffentlich als Items bekannt). Bei der direkten Zuweisung von einem TStrings Derivat auf Items wird ein Assign() aufgerufen, also die interne Items Instanz übernimmt alle Einträge und killt die alten Einträge vorher. Mit anderen Worten: Nach der Zuweisung existiert weiterhin die alte interne Items Instanz und immernoch deine neue foo() Instanz. Daher muss man die von Foo() erzeugte Instanz freigeben danach - so wie die 2 Codebeispiele das schon machen...

MfG
Muetze1

Robert_G 16. Jul 2004 17:02

Re: Funktion erstellt gibt Objekt zurück, wer räumt auf
 
:wall: Na klar!

Mit einer Garbage Collection kann einem auf Dauer sogar das Denken abhanden kommen.
Assign übernimmt nicht das neue Object, nachdem es die alte Instanz "aufgeräumt" hat -> es macht sich nur eine Kopie. :oops:

Delphi-Quellcode:
var
  SL :TStrings;
begin
  // auch wenn es blöd aussieht...
  // Da du IMHO nicht weißt ab wann die SL erzeugt wird, sollte auch foo() in den Try-Except-Block
  try
    SL := foo();
    ListBox.Items.Assign(SL);
  finally
    if Assigned(SL) then
      Free(SL);
      // FreeAndNill halte ich für unnötig, da man mit SL wohl nix mehr machen wird
  end;
end;

mschaefer 17. Jul 2004 14:12

Re: Funktion erstellt gibt Objekt zurück, wer räumt auf
 
Moin, moin,

irgendwie sehe ich keine echten Vorteil in der Verwendung einer Funktion
vor einer Procedureübergabe mit var. Zumal hier das Ergebnis ehedem nicht
gleich weiterverwendet wird (geschachtelte Funktionen).

:?: :!:


Grüße // Martin

Motzi 17. Jul 2004 14:22

Re: Funktion erstellt gibt Objekt zurück, wer räumt auf
 
Kurze Anmerkung.. das
Delphi-Quellcode:
if Assigned(SL) then
im Finally-Teil kann man sich sparen, da Free intern sowieso prüft ob der Self-Pointer nil ist...

jbg 17. Jul 2004 15:28

Re: Funktion erstellt gibt Objekt zurück, wer räumt auf
 
Zitat:

Zitat von supermuckl
Delphi-Quellcode:
var
  SL :TStringList;
begin
  try
    SL := foo();
  finally
    if Assigned(SL) then
      Freeandnil(SL);
  end;
end;

Und nun lass foo mal eine Exception auslösen. Das dein Assigned(SL) diesen Zustand abfängt steht bei 1:4 Mrd.
Die Muster für try/finally sind nämlich:
Delphi-Quellcode:
V := Type.Create;
try
  ...
finally
  V.Free;
end;
und
Delphi-Quellcode:
V := nil;
try
  V := Type.Create;
  ...
finally
  V.Free;
end;
Das V:=nil ist im zweiten Muster wichtig und der Compiler meldet das auch (aber es soll ja Leute geben, die Compiler Warnungen und Hinweise in den Wind schlagen, weil sie doch "unwichtig" sind).

mirage228 17. Jul 2004 15:37

Re: Funktion erstellt gibt Objekt zurück, wer räumt auf
 
Hi Luckie,

wenn du es als "read" property eine Klasse machst, würde ich es so lösen (hatte selbst letztens einen ähnlichen Fall). Undzwar arbeitest du in der Klasse mit einer privaten Liste, die du aussenstehenden zugänglich machst.

Delphi-Quellcode:
TMyClass = class(TObject)
private
  FList: TStringList;
  function GetList: TStrings;
public
  property MyList: TStrings read GetList;
  constructor Create;
  destructor Destroy; override;
end;

// ...

constructor TMyClass.Create;
begin
  inherited;
  FList := TStringList.Create;
end;

destructor TMyClass.Destroy;
begin
  FreeAndNil(FList);
  inherited;
end;

function TMyClass.GetList: TStrings;
begin
  try
    // Mach was mit der FList...
    // ...
    Result := FList;
  except
    Result := nil;
  end;
end;
Ist ungetestet, sollte aber funktionieren.

mfG
mirage228


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:40 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-2025 by Thomas Breitkreuz