Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Speicherfreigabe / Memory Leak (https://www.delphipraxis.net/205325-speicherfreigabe-memory-leak.html)

amigage 27. Aug 2020 15:01

Delphi-Version: 10.4 Sydney

Speicherfreigabe / Memory Leak
 
Hallo,

ich habe wieder ein Problem mit der Speicherfreigabe (ähnlich dem hier: https://www.delphipraxis.net/205273-...freigeben.html )

Ich lese die Anzahl der zu ladenden Icons aus einem MemoryStream und lese dann die ID des jeweiligen Icons ein, um die Grafik dann aus einer vorhanden PNGImageList auszulesen und dann an eine Liste zu übergeben.

Delphi-Quellcode:
// *************************
// Struktur für die Einbindung der Icons
// *************************
  TIconData = class(TObject)
    IconID     : integer;
    Png48 : TPNGImage;
  end;
  TIconList = TObjectList<TIconData>;
Delphi-Quellcode:
procedure ReadIconListFromStream(IconBuffer : TMemoryStream; IconList : TObjectList<TIconData>);
var
  IconData : TIconData;
  iCount : Integer;
  i: Integer;
begin
  IconBuffer.Position := 0;

  IconBuffer.Read(iCount, SizeOf(iCount));

  // und dann in einer Schleife einzeln auslesen
  for I := 0 to iCount-1 do
  begin
    // Nummer des Icons auslesen
    IconBuffer.Read(IconData.IconID, sizeOf(IconData.IconID));

    IconData := TIconData.Create;
    try
      IconData.Png48 := TPngImage.Create;
      IconData.Png48.Assign(MainDlg.pngImageListLeft48Standard.PngImages.Items[IconData.IconID].PngImage);

      IconList.Add(IconData); // ????
    finally
//    IconData.Free; // Memory Leak
    end;
  end;
end;

MainDlg.IconList := TObjectList<TIconData>.Create;
ReadIconListFromStream(IconStream, MainDlg.IconList);
Wir kann ich das IconData an die IconList übergeben, so dass eine Kopie von TIconData entsteht und ich dann das IconData freigeben kann (IconData.Free)?

Ich bedanke mich wieder im Voraus, für einen Hinweis.

himitsu 27. Aug 2020 15:16

AW: Speicherfreigabe / Memory Leak
 
Delphi-Quellcode:
    try
      IconData.Png48 := TPngImage.Create;
      IconData.Png48.Assign(MainDlg.pngImageListLeft48Standard.PngImages.Items[IconData.IconID].PngImage);

      IconList.Add(IconData); // ????
    except
      IconData.Free;
      raise;
    end;
Wozu eine Kopie? Du hast ja schon je Durchlauf ein neues TIconData.
Und das eigentliche Freigeben macht die ObjectList mit OwnsObjects=True.

Aber warum ist das IconBuffer.Read vor dem TIconData.Create?
Der Compiler sollte da eigentlich auch meckern, vonwegen nicht initialisierte Varaible.
Wenn ja, warum hörst du nicht auf ihn?

amigage 27. Aug 2020 16:08

AW: Speicherfreigabe / Memory Leak
 
Zitat:

Und das eigentliche Freigeben macht die ObjectList mit OwnsObjects=True.
Aha, okay. Ich dachte, ich muss mich bereits in der Prozedur um die Freigabe von TIconData kümmern.

Zitat:

Aber warum ist das IconBuffer.Read vor dem TIconData.Create?
Das war mein Fehler beim Reinkopieren, denn eigentlich ist die Prozedur noch etwas umfangreicher.
Natürlich wird TIconData.Create vor dem IconBuffer.Read ausgeführt.:thumb:

Rolf Frei 28. Aug 2020 15:43

AW: Speicherfreigabe / Memory Leak
 
Was ich in deinem Code noch vermisse ist die Freigabe des Png48 Objekts. Wenn TIconData freigegeben wird, muss auch das Png48 freigegeben werden, sonst hagelt es von Memoryleaks. Überschreibe dafür den Destroy Destructor in TIconData:

Delphi-Quellcode:
type
  TIconData = class(TObject)
  public
    IconID : integer;
    Png48 : TObject;
    destructor Destroy(); override;
  end;
  TIconList = TObjectList<TIconData>;


{ TIconData }

destructor TIconData.Destroy;
begin
  Png48.Free;
  inherited;
end;

amigage 29. Aug 2020 13:11

AW: Speicherfreigabe / Memory Leak
 
Zitat:

Zitat von Rolf Frei (Beitrag 1472552)
Was ich in deinem Code noch vermisse ist die Freigabe des Png48 Objekts. Wenn TIconData freigegeben wird, muss auch das Png48 freigegeben werden, sonst hagelt es von Memoryleaks.

Genau das war mein Problem. Danke für den Hinweis. Damit sind die PNG Memory Leaks verschwunden :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 13: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