Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Frage zu .free bei Klassen (https://www.delphipraxis.net/50101-frage-zu-free-bei-klassen.html)

Wuaegner 20. Jul 2005 17:25


Frage zu .free bei Klassen
 
Ich habe eine Klasse TStringManager, die unter anderem das hier enthält:
Delphi-Quellcode:
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;
Initialize erzeugt die Listen, z.B FNummernListe:= TStringList.Create;
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:
StrMg.Close;  // <== Ist das hier nötig, die Listen innerhalb der Klasse zu löschen oder
        StrMg.Free;   // reicht diese Zeile ?
Lasse ich StrMg.Close nämlich weg geht es ohne Fehlermeldung, mit der Zeile kommt eine AV.

Dax 20. Jul 2005 17:27

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.

Wuaegner 20. Jul 2005 17:29

Re: Frage zu .free bei Klassen
 
Kannst du posten wie das dann aussähe?

Dax 20. Jul 2005 17:32

Re: Frage zu .free bei Klassen
 
Delphi-Quellcode:
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;
Das sollte man als OOPer aber wissen.

Wuaegner 20. Jul 2005 17:33

Re: Frage zu .free bei Klassen
 
Habe noch nicht viel Erfahrung mit OOP , drum danke.

Wuaegner 20. Jul 2005 17:55

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.

Dax 20. Jul 2005 17:58

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)

Wuaegner 20. Jul 2005 18:08

Re: Frage zu .free bei Klassen
 
Verwende jetzt FreeAndNil() aber der Fehler kommt immernoch. Es muss also daran liegen
Zitat:

ein nicht instanziiertes Objekt?
Ich erzeuge die Listen mit liste:= TStringList.Create; , füge mit Add() neue Items hinzu und lösche wieder welche usw. , muss ich noch etwas beachten?

malo 20. Jul 2005 18:09

Re: Frage zu .free bei Klassen
 
Zitat:

Zitat von Dax
Tip: Statt .Free lieber FreeAndNil nehmen ;) Tut nix anderes, aber ein erneutes Free dafür nix mehr, also keine AVs (falls es daran lag)

Naja, der Unterschied von FreeAndNil zu .Free ist ja, dass bei FreeAndNil das Objekt freigegeben und die Zeiger auf Nil gesetzt werden (wie der Name schon sagt). Also entspricht FreeAndNil folgemdem Code:
Delphi-Quellcode:
MyObj.Free;
MyObj := nil;
Ob man jetzt die entsprechende Prozedur nutzt oder es selbst macht (oder den Destructor verwendet) bleibt jedem selbst überlaseen.

Dax 20. Jul 2005 18:10

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:

malo 20. Jul 2005 18:13

Re: Frage zu .free bei Klassen
 
Zitat:

Zitat von Wuaegner
Verwende jetzt FreeAndNil() aber der Fehler kommt immernoch. Es muss also daran liegen
Zitat:

ein nicht instanziiertes Objekt?
Ich erzeuge die Listen mit liste:= TStringList.Create; , füge mit Add() neue Items hinzu und lösche wieder welche usw. , muss ich noch etwas beachten?

Naja, wenn eine AV kommt, wird wohl zwangsläufig irgendwo nach der Freigabe des Objekts noch auf das Objekt zugegriffen. Eventuell hilft Debuggen, um die Stelle zu finden ;)

Wuaegner 20. Jul 2005 18:32

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.

Flocke 20. Jul 2005 18:36

Re: Frage zu .free bei Klassen
 
Destroy ruft man nicht direkt auf sondern benutzt Free - oder in diesem Fall noch besser FreeAndNil
Delphi-Quellcode:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAndNil(StrMg);
end;
Obs daran liegt weiß ich jetzt allerdings nicht.

[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;

Wuaegner 20. Jul 2005 18:37

Re: Frage zu .free bei Klassen
 
ok aber daran liegts nicht.

SirThornberry 20. Jul 2005 18:39

Re: Frage zu .free bei Klassen
 
bei sowas
Delphi-Quellcode:
StrMg.FStringList:= StrMg.FCopyList;
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.
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?

Flocke 20. Jul 2005 18:45

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);

Wuaegner 20. Jul 2005 18:48

Re: Frage zu .free bei Klassen
 
Zitat:

Wennd u Button1 mehrmals klickst, kommt dann eignetlich ein Fehler?
Nein dann kommt kein Fehler.
Zitat:

StrMg.FStringList.Assign(StrMg.FCopyList);
Trotzdem kommt immernoch die AV.

BlackJack 20. Jul 2005 18:55

Re: Frage zu .free bei Klassen
 
Delphi-Quellcode:
FreeAndNil(FEinzelListe); [b]// <= HIER KOMMT EINE AV
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.

Wuaegner 20. Jul 2005 18:58

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