![]() |
AV - Warum?
Hi
ich habe eine TreeView die ich dynamisch befülle. da das im laufe des Programms mehrmals vorkommen kann, habe ich mir folgendes überlegt:
Delphi-Quellcode:
aber beim Free'en der Nodes kommt es immer zu ner AV (Wenn sie schon exitieren)
procedure UpdateTreeView;
var i:Integer; begin { ... Daten holen etc. ... } FTree.Items.Clear; //TreeView leeren for i:=0 to Length(FNodes)-1 do //Nodes plattmachen if FNodes[i]<>nil then FNodes[i].Free; SetLength(FNodes,FGruppen.Count+FLieder.Count); //Array setzen for i:=0 to Length(FNodes)-1 do //Nodes erstellen FNodes[i]:=TTreeNode.Create(FTree.Items); { ... Nodes setzen und in TreeView rein ... } end; wenn ich die schleife weglasse habe ich ein monster-Speicherleck was eigentlich nur daher kommen kann. weiss einer was daran falsch ist? bzw wie ich es anders machen kann? Edit: FNodes ist ein array of TTreeNode, FGruppen und FLieder TStringList und FTree eine TreeView. |
Re: AV - Warum?
Moin Gereon,
und an welcher Stelle kommt die AV? |
Re: AV - Warum?
Wenn diese Procedure das zweite mal durchlaufen wird (Also Length(FNodes)>0 bzw die Nodes erstellt sind) direkt beim ersten FNodes[i].Free;
Im codeausschnitt also Zeile 7 Zitat:
|
Re: AV - Warum?
Moin Gereon,
wenn FNodes[i] = nil ist darfst Du FNodes[i].Free nicht aufrufen, also vorher prüfen. |
Re: AV - Warum?
mach ich doch :wall:
Delphi-Quellcode:
Ausserdem kommt ja gerade dann die exception wenn FNodes[i] ungleich nil ist...
for i:=0 to Length(FNodes)-1 do //Nodes plattmachen
if FNodes[i]<>nil then FNodes[i].Free; |
Re: AV - Warum?
Moin Gereon,
:oops: hatte ich übersehen. Was enthält denn FNodes[i]? Wenn Du da im Einzelschritt durchgehst, kannst Du es Dir ja anzeigen lassen. Das der Aufruf von Free den Inhalt nicht auf nil setzt ist klar? |
Re: AV - Warum?
da weiss ich ehrlich gesagt nicht wie ich da drankommen soll :(
es ist ein array of TTreeNode in einer Klasseninstanz dessen deklaration in ner anderen Unit steckt...geht das überhauot mit der "Liste überwachter Ausdrücke"? |
Re: AV - Warum?
Zitat:
Dieser Code
Delphi-Quellcode:
Bringt eine (wahrscheinlich die) exception.
with TObject.Create do
begin Free; Free; end; Mögliche Lösung: Nicht TObject.Free verwenden, sondern FreeAndNil(TObject) btw: if Obj <> nil then Obj.Free bringt nix. In Free selbst wird schon überprüft: if self <> nil then Destroy(); |
Re: AV - Warum?
Hi Gereon,
hast du dynamisch angeforderten Speicher an deine Knoten geknüpft, dann kannst du diesen einfach und sicher im Ereignis OnDeletion() der TreeView wieder freigeben. Außerdem würde ich keine TreeNodes in einer externen Struktur speichern. Es genügt der Data-Ponter des TreeNode auf seine zugehörigen Daten in deiner externen Struktur. Grüße vom marabu |
Re: AV - Warum?
hmm, also ich verstehe nicht so ganz was du meinst...
ich kann die Nodes ja nicht "in" der TreeView selber speichern, oder? afaik müssen die ja in einem seperaten array abgelegt sein. oder liegt da der denkfehler? |
Re: AV - Warum?
Free setzt nicht automatisch den Zeiger auf nil. Das heißt beim zweiten mal versuchst du einen Node freizugeben der im Speicher nicht mehr existiert, weil der Zeiger noch gültig ist schlöagt die Prüfung auf nil fehl. Setz mal den Zeiger noch auf nil nach dem Freigeben des Speichers.
|
Re: AV - Warum?
Moin Gereon,
Zitat:
Jeder Node hat die Eigenschaft Data. Dort kannst Du Pointer zu anderen Objekten speichern, und hast so, fast, direkt Zugriff auf Daten, die zu einem Node gehören. Aber nicht vergessen, dass diese Objekte dann auch wieder freigegeben werden müssen ;-) |
Re: AV - Warum?
Aber:
In dem Array KANN es keine Objekte geben die nicht Erstellt sind. Es gibt nur Objekte die Ordnungsgemäß erstellt wurden. nirgendwo sonst wird auf dieses Array in irgendeiner weise zugegriffen. also wird auch nichts zum zweiten mal freigegeben.... |
Re: AV - Warum?
Hallo,
ich sehe gerade das:
Delphi-Quellcode:
Durch das FTree.Items.Clear werden doch schon die TreeNodes gelöscht (Vorausgesetzt, im Array sind auch die Nodes von FTree).
begin
{ ... Daten holen etc. ... } FTree.Items.Clear; // <------ for i:=0 to Length(FNodes)-1 do //Nodes plattmachen if FNodes[i]<>nil then FNodes[i].Free; Danach steht in deinem Array nur noch ein Pointer ins nichts. Gruß xaromz |
Re: AV - Warum?
achsooo....
wäre es möglich einfach nur die Nodes zu Free'n und das Clear wegzulassen? das wird wohl der Fehler sein... |
Re: AV - Warum?
Warum willst du sie denn Free'n ? Clear sie einfach und fertig.
Ist doch viel einfacher... |
Re: AV - Warum?
Und was ist mit dem belegten Speicher?
|
Re: AV - Warum?
Zitat:
Hinzufügen geschieht so:
Delphi-Quellcode:
Auf diese Weise verknüpfe ich eine Gliederung, die ich in einer Datenbanktabelle abgelegt habe, mit der TreeView. Liegen deine Daten nicht in einer Datenbank, dann verwaltest du sie vielleicht in einer Liste (TList, TObjectList, ...) oder einem array of pointer. Du kannst dann der Data property eines Nodes den Zeiger auf dein DataItem zuweisen und im Ereignis TTreeNode.OnDeletion gibst du den Speicher dann wieder frei:
with TreeView.Items.AddChild(parentNode, nodeText) do
begin Data := Pointer(DataSet.RecNo); // alternativ kannst du den primary key an Data zuweisen ... end;
Delphi-Quellcode:
marabu
procedure TDemoForm.TreeViewDeletion(Sender: TObject; Node: TTreeNode);
begin if Assigned(Node.Data) then TStringList(Node.Data).Free; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:32 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