![]() |
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:
Muss das irgendwie noch speziell aufgerufen werden?
procedure Tfrm_start.VstFreeNode(Sender: TBaseVirtualTree;
Node: PVirtualNode); Var Liste: Tliste; begin Liste := Tliste(Vst.GetNodeData(node)^); Liste.Free; end; |
AW: MemoryLeak bei VirtualStringtree
Zitat:
Im Zweifelsfall wäre mal die Deklaration von TListe interessant. Zeigt EurekaLog nicht mehr Details an, was genau übrig bleibt? |
AW: MemoryLeak bei VirtualStringtree
Es wurde kein Destruktor in TListe extra erstellt, da es sich nur um normale Strings dort handelt.
|
AW: MemoryLeak bei VirtualStringtree
Der Code sollte besser so aussehen:
Delphi-Quellcode:
Dass du "Vst" anstatt "Sender" verwendet hat, kann natürlich böse ins Auge gehen.
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; 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; |
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? |
AW: MemoryLeak bei VirtualStringtree
War die Frage an mich gerichtet Himutsu?
|
AW: MemoryLeak bei VirtualStringtree
Vermutlich, Du dereferenzierst ja bereits im Ausgangspost.
|
AW: MemoryLeak bei VirtualStringtree
Hm, weiß gerad enicht was damit gemeint ist, da ich mich an ein damaliges Tutorial gehalten habe.
|
AW: MemoryLeak bei VirtualStringtree
Zitat:
Delphi-Quellcode:
in deinem Code.
^
Zitat:
oder du hast falsch abgeschrieben. |
AW: MemoryLeak bei VirtualStringtree
Zitat:
Zitat:
Wenn man sich TVirtualNode mal anschaut:
Delphi-Quellcode:
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.
TVirtualNode = packed record
Index, ChildCount: Cardinal; // ... LastChild: PVirtualNode; Data: record end; end; **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** |
AW: MemoryLeak bei VirtualStringtree
Hm also wenn ich es so mach:
Delphi-Quellcode:
Bleibt der Leak bestehen.
procedure Tfrm_start.VstFreeNode(Sender: TBaseVirtualTree;
Node: PVirtualNode); Var Liste: ^Tliste; begin Liste := Sender.GetNodeData(node); Liste^.Free; end; Edit: So werden die Nodes hinzugefügt.
Delphi-Quellcode:
VstFreeNode muss ich nicht noch extra speziell aufrufen oder?
while not Query.Eof do begin
Liste := TListe .Create; with Liste do begin ... Daten end; Node := FVst.AddChild(nil, KundenListe); Node.CheckType:= ctCheckBox; Query.Next; end; |
AW: MemoryLeak bei VirtualStringtree
Gibt es bei dir Nodes, die nicht sichtbar sind? Rufe mal für jede Node, die du hinzufügst
Delphi-Quellcode:
auf. Ich hatte das selbe Problem, was daran liegt, dass für nicht validated Nodes kein OnFreeNode Event aufgerufen wird. Nodes werden standardmäßig erst dann validiert, wenn sie mindestens einmal sichtbar waren.
ValidateNode(Node)
|
AW: MemoryLeak bei VirtualStringtree
Sind alle Sichtbar, kein Node ist unsichtbar.
Angeblich soll hier der Leak sein
Delphi-Quellcode:
KundenListe := TKundenListe.Create;
|
AW: MemoryLeak bei VirtualStringtree
Liste der Anhänge anzeigen (Anzahl: 1)
Siehe Anhang ein Bild, welches mich auch verwirrt. Wieso verursacht die System.pas auch Leaks? Und das alles erst nach dem füllen des VST's
|
AW: MemoryLeak bei VirtualStringtree
Zitat:
Delphi-Quellcode:
zur Sicherheit bitte trotzdem mal.
ValidateNode()
Zitat:
Ich weiß nicht, ob der VST damit zurecht kommt, wenn du direkt eine Klasse bzw. ein Objekt als Node nimmst. Ich gehe immer so vor:
Delphi-Quellcode:
Dann irgendwo zur Initialisierung:
type
PMyNodeData = ^TMyNodeData; TMyNodeData = packed record Liste: TListe; end;
Delphi-Quellcode:
VST.NodeDataSize := SizeOf(TMyNodeData)
Nodes hinzufügen:
Delphi-Quellcode:
Im OnFreeNode Event:
NodeData := VST.GetNodeData(VST.AddChild(nil));
NodeData^.Liste := TListe.Create; // ..
Delphi-Quellcode:
Edit: Der Leak stammt nicht wirklich aus der System.pas. Es wird irgendwo ein UnicodeString erzeugt, welcher nicht mehr freigegeben wird. Lediglich die Funktion zum Erstellen eines neuen Strings befindet sich in der System.pas und wird per compiler magic oder was auch immer automatisch von Delphi aufgerufen, sobald du eine neue String Instanz erzeugst.
NodeData := Sender.GetNodeData(Node);
if Assigned(NodeData) then begin NodeData^.Liste.Free; // Wenn du Strings oder Ähnliches direkt im TMyNodeData Record verwendest einfach noch ein // Finalize(NodeData^) // hinterherschieben end; Edit: Was mir grade noch einfällt: Das Leak könnte sich auch in deiner TListe Klasse befinden. Prüf das am besten auch nochmal. |
AW: MemoryLeak bei VirtualStringtree
Edit: das war es, Leak ist entfernt. Danke Dir. Ich musste also nur das Objekt richtig einbinden
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:25 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