![]() |
Frage zu .free bei Klassen
Ich habe eine Klasse TStringManager, die unter anderem das hier enthält:
Delphi-Quellcode:
Initialize erzeugt die Listen, z.B FNummernListe:= TStringList.Create;
type
TStringManager = class(TObject) // Kapselt private // Stringverarbeitung FNummernListe : TStringlist; // Liste aller Nummern FOrteListe: TStringList; FDatumsListe: TStringList; // Liste aller Daten procedure Initialize; // Listen werden erstellt procedure Close; In der Prozedur Close; wollte ich nich diese Listen wieder freigeben mit FNummernListe.Free usw. Im OnCreate meiner Form wird StrMg:= TStringManager.Create; aufgerufen und im OnClose meiner Form:
Delphi-Quellcode:
Lasse ich StrMg.Close nämlich weg geht es ohne Fehlermeldung, mit der Zeile kommt eine AV.
StrMg.Close; // <== Ist das hier nötig, die Listen innerhalb der Klasse zu löschen oder
StrMg.Free; // reicht diese Zeile ? |
Re: Frage zu .free bei Klassen
Tu dein Zeug in den Constructor und den Destructor, dann hast du wenigstens was davon und musst nicht ewig oft mit diesen sinnlosen Extramethoden rumfummeln.
|
Re: Frage zu .free bei Klassen
Kannst du posten wie das dann aussähe?
|
Re: Frage zu .free bei Klassen
Delphi-Quellcode:
Das sollte man als OOPer aber wissen.
type
TStringManager = class private {Felder} public constructor Create; destructor Destroy; override; end; constructor TStringManager.Create; begin // Felder erstellen // also der Initialize-Code end; destructor TStringManager.Destroy; begin // der Close-Code inherited; end; |
Re: Frage zu .free bei Klassen
Habe noch nicht viel Erfahrung mit OOP , drum danke.
|
Re: Frage zu .free bei Klassen
Ok habe es jetzt so gemacht, das Problem besteht aber weiterhin.
Muss ich im destructor die einzelnen Listen ".free" en oder nicht? Wenn ich es mache kommt eine AV, wenn nicht geht es. |
Re: Frage zu .free bei Klassen
Wurden die Listen vielleicht schon vorher freigegeben, oder verwendest du vielleicht sogar ein nicht instanziiertes Objekt? Anders ist dieses Verhalten nicht erklärbar.
Tip: Statt .Free lieber FreeAndNil nehmen ;) Tut nix anderes, aber ein erneutes Free dafür nix mehr, also keine AVs (falls es daran lag) |
Re: Frage zu .free bei Klassen
Verwende jetzt FreeAndNil() aber der Fehler kommt immernoch. Es muss also daran liegen
Zitat:
|
Re: Frage zu .free bei Klassen
Zitat:
Delphi-Quellcode:
Ob man jetzt die entsprechende Prozedur nutzt oder es selbst macht (oder den Destructor verwendet) bleibt jedem selbst überlaseen.
MyObj.Free;
MyObj := nil; |
Re: Frage zu .free bei Klassen
Ein bisschen mehr Code könnte ein bisschen mehr helfen ;) Oder ist dein Projekt fürs Militär? :mrgreen:
|
Re: Frage zu .free bei Klassen
Zitat:
|
Re: Frage zu .free bei Klassen
Delphi-Quellcode:
type
TStringManager = class private FNummernListe : TStringlist; FOrteListe: TStringList; FDatumsListe: TStringList; FLaengenListe: TStringList; FKostenListe: TStringList; FStringList: TStringList; FCopyList: TStringList; FEinzelListe: TStringList; procedure ClearToErsteZeile; procedure ClearGarbage; procedure FillFEinzelListe; procedure SplitString(s:string); procedure StrToListen; function Kosten(nr: string):real; function LoadFile(FileName:string): boolean; function IsValid(s: string):boolean; public constructor Create; destructor Destroy; override; end; var Form1: TForm1; StrMg: TStringManager; implementation {$R *.dfm} { TStringManager } procedure TStringManager.ClearGarbage; var i: integer; s: string; anzahl: integer; begin ClearToErsteZeile; // Unwichtiges davor wird gelöscht for i:= FStringList.Count-1 downto 0 do begin if (pos('*',FStringList.Strings[i])=0) then FStringList.Delete(i); end; . . . end; constructor TStringManager.Create; begin FNummernListe:= TStringList.Create; FEinzelListe:= TStringList.Create; FDatumsListe:= TStringList.Create; FOrteListe:= TStringList.Create; FLaengenListe:= TStringList.Create; FKostenListe:= TStringList.Create; FCopyList:= TStringList.Create; FStringList:= TStringList.Create; end; destructor TStringManager.Destroy; begin FreeAndNil(FNummernListe); FreeAndNil(FEinzelListe); [b]// <= HIER KOMMT EINE AV FreeAndNil(FDatumsListe); FreeAndNil(FOrteListe); FreeAndNil(FLaengenListe); FreeAndNil(FKostenListe); FreeAndNil(FCopyList); FreeAndNil(FStringList); [b]// UND HIER ( auskommentiert läuft es) inherited; end; procedure TStringManager.FillFEinzelListe; var i, k: Integer; begin FEinzelListe:= FNummernListe; For i := FEinzelListe.Count - 2 downto 0 do For k := FEinzelListe.Count - 1 downto i + 1 do If FEinzelListe.Strings[i] = FEinzelListe.Strings[k] Then FEinzelListe.Delete(k); end; function TStringManager.IsValid(s: string): boolean; begin result:= false; if s[3]='.' then result:= true; end; procedure TForm1.FormCreate(Sender: TObject); begin StrMg:= TStringManager.Create; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin StrMg.Destroy; end; procedure TForm1.Button1Click(Sender: TObject); var h,i: integer; begin for h:= 1 to 9 do begin if StrMg.LoadFile('telekom_'+IntToStr(h)+'.txt') then begin StrMg.ClearGarbage; for i:= 0 to StrMg.FStringList.Count-1 do begin StrMg.FCopyList.Add(StrMg.FStringList.Strings[i]); end; StrMg.FStringList.Clear; end; end; StrMg.FStringList:= StrMg.FCopyList; StrMg.StrToListen; StrMg.FillFEinzelListe; LBNummern.Items:= StrMg.FEinzelListe; end; end. |
Re: Frage zu .free bei Klassen
Destroy ruft man nicht direkt auf sondern benutzt Free - oder in diesem Fall noch besser FreeAndNil
Delphi-Quellcode:
Obs daran liegt weiß ich jetzt allerdings nicht.
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin FreeAndNil(StrMg); end; [Nachtrag] FreeAndNil macht übrigens genau das hier:
Delphi-Quellcode:
procedure FreeAndNil(var Obj);
var Temp: TObject; begin Temp := TObject(Obj); Pointer(Obj) := nil; Temp.Free; end; |
Re: Frage zu .free bei Klassen
ok aber daran liegts nicht.
|
Re: Frage zu .free bei Klassen
bei sowas
Delphi-Quellcode:
ist das ganze kein Wunder. damit verwirfst du den InstanzPointer von StrMg.FStringlist und weiß einfach eine andere Instanz zu. Da wird nix kopiert außer der zeiger auf die Liste.
StrMg.FStringList:= StrMg.FCopyList;
Desweiteren ist der Privatebereich dafür da das andere Objecte nicht auf die dinge Zugreifen, in deinem Fall greifst du aber von deinem TForm-Object auf den Privatebereich von deinem Manager zu, dann kannst du das mit dem Private auch lassen :roll: Wennd u Button1 mehrmals klickst, kommt dann eignetlich ein Fehler? |
Re: Frage zu .free bei Klassen
Stimmt :wall: ... habe ich auch übersehen.
Was du tun willst ist wahrscheinlich
Delphi-Quellcode:
StrMg.FStringList.Assign(StrMg.FCopyList);
|
Re: Frage zu .free bei Klassen
Zitat:
Zitat:
|
Re: Frage zu .free bei Klassen
Delphi-Quellcode:
da du die liste richtig erstellst und auch wieder richtig freigibst, kann der fehelr nur entstehen, weil du zwischendurch FEinzelListe freigibst oder überschreibst (wie SirThornberry beretis erklärt hat). da du jetzt die fehlerursache kennst, ist ein wenig eigeninitiative gefragt, also geh durch den gesatmen source nud schau nach wo du FEinzelListe überschreibst oder fregibst.
FreeAndNil(FEinzelListe); [b]// <= HIER KOMMT EINE AV
|
Re: Frage zu .free bei Klassen
JAWOHL!
Habe noch einmal im Code kein .Assign benutzt , daran lag's. Danke an alle Helfenden! :thumb: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:16 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