![]() |
Zeiger freigeben
Hallo
Beim Freigeben von Zeiger habe ich nicht ganz den Durchblick. Gegeben ist folgender Code (von zwei Klassen):
Delphi-Quellcode:
Soll ich nun den Zeiger wie ich's gemacht habe in der zweiten Funktion disposen oder macht man in solchen Fällen in der TestClassA eine Prozedur, die dann einfach dispose(PTestRecord) aufruft (und in der Button1Click-Prozedur aufgerufen wird)?
function TTestClassA.getListe: TList;
var List : TList; PTestRecord : ^TTestRecord; begin new(PTestRecord); List := TList.Create; PTestRecord^.FeldA := 'Hallo'; PTestRecord^.FeldB := 'Test'; PTestRecord^.FeldC := 1; List.Add(PTestRecord); Result := List; end; procedure TForm1.Button1Click(Sender: TObject); var List : TList; TestClassA : TTestClassA; PTestRecord : ^TTestRecord; begin TestClassA := TTestClassA.Create; List := TestClassA.getListe; PTestRecord := List.Items[0]; Label1.Caption := PTestRecord^.FeldA; Dispose(PTestRecord); end; Die selbe Frage stellt sich natürlich auch wenn man statt mit TList mit TObjectList arbeiten würde (und dann Objekte auflistet). Dann würde aber nur der Weg über eine Funktion der Klasse TTestClassA funtktionieren, oder? Ich wäre froh wenn mir jemand den "Standardweg" aufzeigen könnte. Danke und Gruss Tom |
DP-Maintenance
Dieses Thema wurde von "alcaeus" von "Programmieren allgemein" nach "Object-Pascal / Delphi-Language" verschoben.
Ist eine Frage zu Object Pascal |
Re: Zeiger freigeben
Moin!
Zitat:
Grundsätzlich musst du den Speicher für den Record freigeben, wenn du den Eintrag löscht in der Liste - weil die Liste verwaltet nur Zeiger, die zweiss nix von dem Typ und kann daher auch nicht den Speicher freigeben. Zitat:
Ausserdem hat die TObjectlist die einfache Möglichkeit das man ihr sagen kann (ist sogar Standardeinstellung ->OwnsObjects), dass sie beim Entfernen eines Objektes aus der Liste, dieses auch freigibt (->Delete()). Wenn dies nicht gewünscht ist, dann kann man auch Remove() nutzen, welches das Objekt zurück gibt, den Eintrag aus der Liste entfernt aber das Objekt nicht freigibt. MfG Muetze1 |
Re: Zeiger freigeben
Tag auch
Danke erstmal für die Infos. Vielleicht erst zu den Zeigern: Das Dispose in Button1Click ist demzufolge unnötig. Wie und vor allem wann müsste aber nun in meinem Beispiel Dispose aufgerufen werden? Sehe ich das zudem richtig dass ich mit TList ein Speicherleck geschaffen habe (List wird in getListe nicht zerstört, darf aber auch nicht sein da ansonsten in Button1Click nicht mehr verfügbar --> wann und wie soll ich List freigeben?). Ich wäre froh wenn jemand mein Bespiel so ändern könnte, das alles richtig funktioniert und schlussendlich richtig freigegeben wird. Danke und Gruss Tom |
Re: Zeiger freigeben
Ich hab's mal selbst probiert:
Delphi-Quellcode:
PTestRecord in TTestClassA müsste als Membervariable von TTestClassA definiert werden damit sie in Destroy zerstört werden kann.
function TTestClassA.getListe: TList;
var List : TList; begin new(PTestRecord); List := TList.Create; PTestRecord^.FeldA := 'Hallo'; PTestRecord^.FeldB := 'Test'; PTestRecord^.FeldC := 1; List.Add(PTestRecord); Result := List; List.Free; end; procedure TTestClassA.Destroy; begin Dispose(PTestRecord); end; procedure TForm1.Button1Click(Sender: TObject); var List : TList; TestClassA : TTestClassA; PTestRecordKopie : ^TTestRecord; begin TestClassA := TTestClassA.Create; List := TestClassA.getListe; PTestRecordKopie := List.Items[0]; Label1.Caption := PTestRecordKopie^.FeldA; List.Free; TestClassA.Destroy; end; Stimmt das so? Danke und Gruss Tom |
Re: Zeiger freigeben
|
Re: Zeiger freigeben
Zitat:
Zitat:
Zitat:
|
Re: Zeiger freigeben
Hallo alle,
das mit dem Freigeben vom Listenobjekt habe ich inzwischen so gelöst, indem ich die Liste der function getListe als var-Parameter übergebe. Es bleibt aber immer noch die Frage, wo und wann ich den mit new(PTestRecord) reservierten Speicher freigeben kann/soll... (ich denke ich kann new(PTestRecord) nicht im Konstruktor aufrufen da ich nicht weiss wie oft die Funktion getListe nacheinander aufgerufen wird) Danke und Gruss Tom |
Re: Zeiger freigeben
Hallo,
ein kurzer Kommentar: einen Zeiger kann man nicht freigeben, höchstens reservierten Speicher! Ein Zeiger ist nichts als eine Adresse. Rainer |
Re: Zeiger freigeben
Warum willst du unbedingt it records und Zeigern arbeiten?
Alki hat in der CodeLib ein ![]() Damit ist folgendes möglich: Eine Klasse, die dein Item darstellt (die Liste wird durch ein paar Extra runden des Compilers angelegt ;) ):
Delphi-Quellcode:
Die Verwendung ist absolut easy. :)
uses Contnrs;
type TTest = class private fSomeValue: Integer; public property SomeValue: Integer read fSomeValue; procedure DoSomething; constructor Create(aSomeValue :Integer); virtual; end; _LIST_ITEM_ = TTest; {$DEFINE TYPED_LIST_TEMPLATE} {$INCLUDE ObjList_Tmpl.pas} TTestList = _LIST_; implementation {$INCLUDE ObjList_Tmpl.pas} { TestClass } constructor TTest.Create(aSomeValue: Integer); begin fSomeValue := aSomeValue; end; procedure TTest.DoSomething; begin Writeln(SomeValue); end;
Delphi-Quellcode:
Ohne ^, @, Typecasts, anderes Gefriemel... :-) (Die Typecasts sind ja schon im Template versteckt :zwinker: )
procedure TTestUsage.DoSomething;
var List : TTestList; Item : TTest; Counter : Integer; begin List := TTestList.Create(); try for Counter := 1 to 100 do begin Item := TTest.Create(Counter); List.Add(Item); end; for Counter := 0 to List.Count do begin List[Counter].DoSomething(); // ohne type cast :-) end; finally List.Free(); end; end; |
Re: Zeiger freigeben
Besten Dank für den Tip. Das hört sich ja ganz interessant an. Darauf werde ich sicher noch zurückgreifen.
Zitat:
Trotzdem lässt mich jetzt mein Problem nicht mehr los.. :gruebel: Oder muss man ganz einfach sagen, dass mein Problem so nicht gelöst wird (mit Zeigern)? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:55 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