![]() |
Dispose: Pointer oder Object?
Hallo, ich habe eine Frage zu Dispose:
Ich hänge an die Nodes einer TreeView Record-Objekte an:
Delphi-Quellcode:
Nun möchte ich den reservierten Speicher bei Programmende freigeben:
type
PNoteRec = ^TNoteRec; TNoteRec = record Caption: string; ID: string; end; implementation procedure TformMain.BaumElementHinzufuegen(const TV: TTreeView); var NewNode: TTreeNode; NoteRecPtr: PNoteRec; begin New(NoteRecPtr); NoteRecPtr^.Caption := 'XYZ'; NoteRecPtr^.ID := 'ZYX'; NewNode := TV.Items.AddChildObject(TV.Items[0], 'XYZ', NoteRecPtr); // ...
Delphi-Quellcode:
oder:
Dispose(TV.Items[j].Data);
Delphi-Quellcode:
Welche der beiden Dispose-Varianten muss ich verwenden?
Dispose(PNoteRec(TV.Items[j].Data));
|
Re: Dispose: Pointer oder Object?
In dem Fall kannst Du die Typinformation weglassen. Das Speichermanagement funktioniert.
|
Re: Dispose: Pointer oder Object?
Zitat:
|
Re: Dispose: Pointer oder Object?
Zitat:
Also ich würde das Freigeben dann dort drin machen. Und jbg hat Recht. |
Re: Dispose: Pointer oder Object?
Und wieso findet dann Memcheck das so erzeugte vermeintliche Speicherleck nicht? Ich habe das ganz ohne Dispose getestet und natürlcih gab es ein Leck. Beide Varianten mit Dispose (mit / ohne Typecast) brachten kein Leck.
|
Re: Dispose: Pointer oder Object?
Hmmm, eigentlich müßte ein Leck entstehen ... wie hast'n das getestet?
Etwas Code wäre nett, nicht daß du über einen der Sonderfälle bei den Strings gestolpert bist :angel2: |
Re: Dispose: Pointer oder Object?
Mit Eurekalog und eingeschaltetem Memcheck. Allerdings habe ich nur ein NoteRec erzeugt mit den ersten 3 Zeilen der Prozedur:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var NoteRecPtr: PNoteRec; begin New(NoteRecPtr); NoteRecPtr^.Caption := 'XYZ'; NoteRecPtr^.ID := 'ZYX'; Dispose(NoteRecPtr); end; |
Re: Dispose: Pointer oder Object?
'XYZ' ist eine untypisierte Konstante und bei Strings liegen untypisierte Konstanten nicht im RAM.
versuch's mal statt mit 'ner Konstante über eine dieser 3 Varianten :mrgreen:
Delphi-Quellcode:
NoteRecPtr^.Caption := IntToStr(123);
SetLength(NoteRecPtr^.Caption, 3); NoteRecPtr^.ID := 'XYz'; NoteRecPtr^.ID[3] := 'Z'; |
Re: Dispose: Pointer oder Object?
Komisch, wenn ich NACH dem Dispose die Record-Daten abfrage, bekomme ich bei beiden Dispose-Arten ein jeweils anderes Ergebnis:
Hier werden im zweiten MessageDlg die Record-Daten weiterhin angezeigt:
Delphi-Quellcode:
Und hier wird im zweiten MessageDlg gähnende Leere angezeigt:
MessageDlg(PNoteRec(TL.Items[j].Data)^.Caption, mtInformation, [mbOK], 0);
Dispose(TL.Items[j].Data); MessageDlg(PNoteRec(TL.Items[j].Data)^.Caption, mtInformation, [mbOK], 0);
Delphi-Quellcode:
Bei beiden Dispose-Arten entsteht jedoch durch den Zugriffsversuch auf die Record-Daten NACH dem Dispose kein (Zeiger-)Fehler, obwohl mit Dispose der Speicher bzw. der Zeiger auf den Speicher ja freigegeben worden sein müsste!?
MessageDlg(PNoteRec(TL.Items[j].Data)^.Caption, mtInformation, [mbOK], 0);
Dispose(PNoteRec(TL.Items[j].Data)); MessageDlg(PNoteRec(TL.Items[j].Data)^.Caption, mtInformation, [mbOK], 0); |
Re: Dispose: Pointer oder Object?
nach dem Freigeben von Speicher sollte man eh nicht mehr versuchen darauf zuzugreifen.
Nur weil mit Dispose (oder sonstwas) spehcer freigegeben wurde, kann ers sein, daß dieser dennoch vom Speichermanager reserviert ist (schlimmstenfalls wird dieser Speicher sogar inzwischen für was Anderes verwendet) bei Dispose werden die Strings freigegeben, wobei der interne Stringzeiger nun auf NIL steht ... drum zeigt das Zweite nichts mehr an, wärend (wie schon gesagt) Dispose ohne Typeninformationen die Strings nicht freigibt und auch nicht den Record nullt ... drum kannst du beim Ersten noch alles auslesen (das erwähnte Speicherleck) PS: wenn der Speichermanager den ganzen Speicherbereich freigegeben hätte, dann hättest du bei beiden Varianten eine Zugriffsverletzung geerntet. (der Speichermanager reserviert große Speicherbereiche und gibt diesen in kleineren Portionen weiter ... ist optimaler so) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:26 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 by Thomas Breitkreuz