Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   MemoryLeak bei VirtualStringtree (https://www.delphipraxis.net/171942-memoryleak-bei-virtualstringtree.html)

youuu 3. Dez 2012 17:59

MemoryLeak bei VirtualStringtree
 
Hi, EurekaLog zeigt mir beim schließen immer ein MemoryLeak an von den Daten des Vst.

Die Daten des Vst werden so freigegeben.

Delphi-Quellcode:
procedure Tfrm_start.VstFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
Var
  Liste: Tliste;
begin
  Liste := Tliste(Vst.GetNodeData(node)^);
  Liste.Free;
end;
Muss das irgendwie noch speziell aufgerufen werden?

uligerhardt 3. Dez 2012 18:06

AW: MemoryLeak bei VirtualStringtree
 
Zitat:

Zitat von youuu (Beitrag 1194166)
Hi, EurekaLog zeigt mir beim schließen immer ein MemoryLeak an von den Daten des Vst.

Die Daten des Vst werden so freigegeben.

Delphi-Quellcode:
procedure Tfrm_start.VstFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
Var
  Liste: Tliste;
begin
  Liste := Tliste(Vst.GetNodeData(node)^);
  Liste.Free;
end;
Muss das irgendwie noch speziell aufgerufen werden?

Schuss ins Blaue: Ist der Destruktor von TListe auch virtuell?
Im Zweifelsfall wäre mal die Deklaration von TListe interessant. Zeigt EurekaLog nicht mehr Details an, was genau übrig bleibt?

youuu 3. Dez 2012 18:08

AW: MemoryLeak bei VirtualStringtree
 
Es wurde kein Destruktor in TListe extra erstellt, da es sich nur um normale Strings dort handelt.

shmia 3. Dez 2012 18:44

AW: MemoryLeak bei VirtualStringtree
 
Der Code sollte besser so aussehen:
Delphi-Quellcode:
procedure Tfrm_start.VstFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
  P: ^TObject;
begin
  P := Sender.getNodeData(Node);
  if Assigned(P) then
  begin
      P^.Free;
      P^ := nil; // zur Sicherheit
  end;
end;
Dass du "Vst" anstatt "Sender" verwendet hat, kann natürlich böse ins Auge gehen.
Eventuell lässt sich das noch so vereinfachen: (kann's nicht testen mangels VirtualTree Komponente)
Delphi-Quellcode:
procedure Tfrm_start.VstFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
  P: ^TObject;
begin
  P := Sender.getNodeData(Node);
  FreeAndNil(P^);
end;

himitsu 3. Dez 2012 18:47

AW: MemoryLeak bei VirtualStringtree
 
Du hast wirklich statt der Objektreferenz einen Zeiger auf eine Variable mit der Objektreferenz in NodeData drin?

Und wie sind die TList-Instanzen dort reingekommen?

youuu 3. Dez 2012 19:26

AW: MemoryLeak bei VirtualStringtree
 
War die Frage an mich gerichtet Himutsu?

DeddyH 3. Dez 2012 19:32

AW: MemoryLeak bei VirtualStringtree
 
Vermutlich, Du dereferenzierst ja bereits im Ausgangspost.

youuu 4. Dez 2012 12:23

AW: MemoryLeak bei VirtualStringtree
 
Hm, weiß gerad enicht was damit gemeint ist, da ich mich an ein damaliges Tutorial gehalten habe.

himitsu 4. Dez 2012 12:42

AW: MemoryLeak bei VirtualStringtree
 
Zitat:

Zitat von youuu (Beitrag 1194263)
Hm, weiß gerad enicht was damit gemeint ist,

Das
Delphi-Quellcode:
^
in deinem Code.

Zitat:

Zitat von youuu (Beitrag 1194263)
da ich mich an ein damaliges Tutorial gehalten habe.

Dann würde ich einfach mal behaupten dieses Tutorial ist der totale Schrott, (auch wenn ich den rest davon jetzt natürlich nicht kenne)
oder du hast falsch abgeschrieben.

jbg 4. Dez 2012 17:32

AW: MemoryLeak bei VirtualStringtree
 
Zitat:

Zitat von shmia (Beitrag 1194174)
P := Sender.getNodeData(Node);
if Assigned(P) then

Unnütz. Sender.GetNodeData liefert hier nie nil, da weder Node=nil, noch Node=RootNode, noch NodeDataSize=0 ist, denn OnFreeNode wird für diese Konstellation nicht aufgerufen.


Zitat:

P^ := nil; // zur Sicherheit
Zur Sicherheit kann man den Speicherbereich direkt vor der Freigabe auch noch mit Nullen füllen.


Wenn man sich TVirtualNode mal anschaut:
Delphi-Quellcode:
TVirtualNode = packed record
  Index,
  ChildCount: Cardinal;
  // ...
  LastChild: PVirtualNode;
  Data: record end;
end;
dann sieht man, dass Sender.GetNodeData (vereinfacht) @Node.Data zurückliefert und das "P^ := nil" nichts anderes ist, als die 4 bzw. 8 Byte die hinter Data sind mit Nullen zu überschreiben. Und das direkt vor der Freigabe des Speicherbereichs.



**Sorry, hab mich nur gerade über eine viel zu langsame Migration geärgert, die, wenn ordnetlich programmiert, in 3 Minuten erledigt wäre und nicht wie jetzt, die ganze Nacht durchlaufen muss**


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:49 Uhr.
Seite 1 von 2  1 2      

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