Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Funktionsrückgabe freigeben (https://www.delphipraxis.net/88072-funktionsrueckgabe-freigeben.html)

Guido Eisenbeis 9. Mär 2007 16:05


Funktionsrückgabe freigeben
 
Hallo.

Es geht um Funktionen, die für die Rückgabe einen Datentyp besitzen, der innerhalb der Funktionen ersteinmal erstellt werden muss.

Als Beispiel soll folgender Code dienen, den ich in einem älteren Posting fand:

Delphi-Quellcode:
function GetFileIcon(AFileName: string; AIndex: integer = 0): TIcon;
begin
  Result := TIcon.Create;
  Result.Handle := ExtractIcon(HInstance, PCHAR(AFileName), AIndex);
end;
Ich habe zum Testen nun simpel und einfach eine Zuweisung vorgenommen, die auch tadellos funktioniert:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  // Icon aus Exe auslesen und Image zuweisen
  Image1.Picture.Graphic := GetFileIcon('C:\Windows\NotePad.exe');
end;
Startet man nun den Taskmanager, so kann man schön beobachten, wie der Speicherbedarf dieser Testanwendung steigt, wenn man vielfach auf den Button klickt.

Nun betrachte ich stattdessen eine Prozedur als Lösung, bei der ich im ButtonClick eine TIcon-Variable anlege, erstelle und der Prozedur als Var-Parameter übergebe. Kehrt der Ablauf nach der Prozedur in das ButtonClick zurück, erfolgt die Zuweisung an Image1.Picture.Graphic. Danach gebe ich diese TIcon-Variable im ButtonClick frei.

Hierbei ist im Taskmanager beim Klicken auf den Button kein Zuwachs an Speicherbedarf zu erkennen.


Fazit:
Offensichtlich werden die Speicherresourcen nicht freigegeben, die von der Funktionen mit TIcon als Datentyp belegt wurden.

Frage:
Wie kann man den belegten Speicher einer Funktionen, wie sie in obigen Beispiel zu sehen ist, wieder freigeben?


Guido.

hoika 9. Mär 2007 16:08

Re: Funktionsrückgabe freigeben
 
Hallo,

probier mal

Delphi-Quellcode:
Icon:= GetFileIcon('C:\Windows\NotePad.exe');
Image1.Picture.Graphic.Assign(Icon);
Icon.Free;

Heiko

NormanNG 9. Mär 2007 16:10

Re: Funktionsrückgabe freigeben
 
Hi,

das hat mit Funktion bzw. Prozecuren direkt doch nichts zu tun. Du schreibst doch selbst
Zitat:

Danach gebe ich diese TIcon-Variable im ButtonClick frei.
Wenn du das nur in der Prozedur-Variante machts, bleibt der Speicher eben bei der Funktion belegt und liegt als Trümmer im Speicher rum...

Guido Eisenbeis 9. Mär 2007 16:47

Re: Funktionsrückgabe freigeben
 
Zunächst mal danke für eure Antworten.

Zitat:

Zitat von hoika
Hallo,

probier mal

Delphi-Quellcode:
Icon:= GetFileIcon('C:\Windows\NotePad.exe');
Image1.Picture.Graphic.Assign(Icon);
Icon.Free;
Heiko

@Heiko:
Wie gesagt, probiert habe ich selbst schon (auch diese Möglichkeit). An Lösungen bin ich interessiert. Denn hierbei wird lediglich der Speicher für "Icon" freigegeben, NICHT der von der Funktion belegte!


Dann hätte ich gerne gewust, wie ihr Postings lest!? Jetzt habe ich mich doch wirklich bemüht, das Problem möglichst verständlich zu beschreiben. Und um zu unterscheiden was gemeint ist, habe ich Prozedur und Funktion farblich hervorgehoben!

Zitat:

Zitat von NormanNG
das hat mit Funktion bzw. Prozecuren direkt doch nichts zu tun. Du schreibst doch selbst
Zitat:

Danach gebe ich diese TIcon-Variable im ButtonClick frei.
Wenn du das nur in der Prozedur-Variante machts, bleibt der Speicher eben bei der Funktion belegt und liegt als Trümmer im Speicher rum...

Genau das habe ich geschrieben, genau das ist die Fragestellung! Also, ich bin ja willig: Wie mache ich das?


Guido.

brechi 9. Mär 2007 17:14

Re: Funktionsrückgabe freigeben
 
Indem man keine Funktionen nimmt die da drin ein Objekt erstellen. Sowas ist totaler Müll, Prozeduren mit var Parmatern sollte man benutzen.

Hat man dennoch mal das Problem (und zwar wenn man scheisse Programmiert hat) dann geht das so:

Delphi-Quellcode:
Icon := IrgendNefuntionDieNenIconZurückgibt;
// ... was mit icon amchen
Icon.Free;
Das was du da schreibst (mit Assign) is eigentlich so richtig gemacht, weiß nicht was du da noch freigeben willst ausser
Bitmap.Assign(nil) vill

sirius 9. Mär 2007 17:48

Re: Funktionsrückgabe freigeben
 
Und um noch brechis Aussage zu ergänzen: Es ist dann sehr hilfreich (finde ich), wenn diese Funktion im Namen irgendetwas von "create" mit drin hat. Das hilft bei der Fehlersuche :mrgreen:

@brechi, sollte man die Variable nicht mit const übergeben?

Christian Seehase 9. Mär 2007 17:57

Re: Funktionsrückgabe freigeben
 
Moin Zusammen,

um das Ganze mal zu verallgemeinern:

Delphi-Quellcode:
// Das const soll verhindern, dass man sich den Pointer auf das Objekt zerschiesst
procedure IchMacheWasMitIrgendeinemObjekt(const AObjekt : TIrgendeineKlasse);
begin
  //...
end;

var
  ObjektVariable : TIrgendeineKlasse;

begin
  ObjektVariable := TIrgendeinKlasse.Create;
  try
    IchMacheWasMitIrgendeinemObjekt(ObjektVariable);
  finally
    FreeAndNil(ObjektVariable); // oder ObjektVariable.Free;
  end;
end;
Es ginge statt der Prozedur natürlich auch eine Funktion, solange diese kein Objekt zurückliefert.

IngoD7 9. Mär 2007 18:02

Re: Funktionsrückgabe freigeben
 
Kleine Zwischenfrage:
Welche Unit brauche ich, um ExtractIcon(HInstance, PCHAR(AFileName), AIndex) benutzen zu können? :gruebel:
Danke.

Luckie 9. Mär 2007 18:06

Re: Funktionsrückgabe freigeben
 
Windows?

Angel4585 9. Mär 2007 18:07

Re: Funktionsrückgabe freigeben
 
Ich verwende immer sowas:

Delphi-Quellcode:
function IchGebeEinObjectZurueck : TMeinObject;
begin
Result:=TMeinObject.Create;
end;

.
.
begin
with IchGebeEinObjectZurueck do
  try
//    Tu was..
  finally
    Free;
    end;
end;
Was ist daran falsch? Ich gebe es ja wieder frei oder?


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:07 Uhr.
Seite 1 von 4  1 23     Letzte »    

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