Fragen zu "ObjektReferenz.Free" und "ObjektReferenz := nil"

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
mintpc
Beiträge: 124
Registriert: Mo 6. Sep 2010, 18:39
OS, Lazarus, FPC: Win 7 (L 1.6 FPC 3.0.0)
CPU-Target: Win 7
Wohnort: Mailand

Fragen zu "ObjektReferenz.Free" und "ObjektReferenz := nil"

Beitrag von mintpc »

Hallo zusammen,
ich hab zwar schon etliche Seiten gegoogelt und im Lazarus-Buch nachgesehen, bin mir aber immer noch nicht schlüssig.

Als Beispiel wurde ein Objekt erzeugt: ObjektReferenz := TBeispielKlasse.create;

Frage 1: Ist es richtig, dass beim Aufruf von "free" die Referenze nicht unbedingt auf nil gesetzt wird?
Also, dass bei ObjektReferenz.Free nicht unbedingt (ObjektReferenz = nil) gelten muss, sondern
ObjektReferenz auch auf "Datenschrott" oder irgend etwas anderes zeigen kann?

Frage 2: Wird bei ObjektReferenz := nil immer noch vorher ObjektReferenz.destroy oder ObjektReferenz.free aufgerufen,
oder schwirrt dann immer noch ein nicht mehr referenziertes Objekt nebst Speicherplatz irgendwo im Speicher rum
und beleg Speicherplatz?

Vielen Dank schonmal für eine Antwort.
mintpc

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Fragen zu "ObjektReferenz.Free" und "ObjektReferenz := n

Beitrag von Michl »

mintpc hat geschrieben:Frage 1: Ist es richtig, dass beim Aufruf von "free" die Referenze nicht unbedingt auf nil gesetzt wird?
Also, dass bei ObjektReferenz.Free nicht unbedingt (ObjektReferenz = nil) gelten muss, sondern
ObjektReferenz auch auf "Datenschrott" oder irgend etwas anderes zeigen kann?
Diese Referenz kann irgendwohin zeigen. Kannst Du einfach auch mal testen:

Code: Alles auswählen

type
  TMyClass = Class(TComponent)
  end; 
var
  MyClass: TMyClass;
...                     
procedure TForm1.Button1Click(Sender: TObject);
begin
  MyClass:=TMyClass.Create(Nil);
  MyClass.Free;
  if MyClass = Nil
    then Caption:='Meine Klasse existiert nicht mehr und hat die Referenz Nil'
    else Caption:='Meine Klasse existiert nicht mehr, Referenz ist aber nicht Nil';
end;
mintpc hat geschrieben:Frage 2: Wird bei ObjektReferenz := nil immer noch vorher ObjektReferenz.destroy oder ObjektReferenz.free aufgerufen,
oder schwirrt dann immer noch ein nicht mehr referenziertes Objekt nebst Speicherplatz irgendwo im Speicher rum
und beleg Speicherplatz?
Auch die Antwort auf diese Frage kannst Du einfach selber herausfinden. Müsstest mal bei den Projekteinstellungen unter Debuggen "Heaptrc-Unit verwenden" einschalten (diese findet Speicherleichen) und folgenden Code ausführen:

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
begin
  MyClass:=TMyClass.Create(Nil);
  MyClass:=Nil;
end;  
Antwort: Du hast eine Speicherleiche erstellt. Also immer .Free, bevor Du .Nil aufrufst oder FreeAndNil verwenden...

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

mintpc
Beiträge: 124
Registriert: Mo 6. Sep 2010, 18:39
OS, Lazarus, FPC: Win 7 (L 1.6 FPC 3.0.0)
CPU-Target: Win 7
Wohnort: Mailand

Re: Fragen zu "ObjektReferenz.Free" und "ObjektReferenz := n

Beitrag von mintpc »

Hallo Michl,

erstmal vielen Dank für die schnelle Antwort und ja, es stimmt, man kann das tatsächlich
schnell selbst herausfinden ... aber wenn der Kopf raucht ist man oft "betriebsblind".
Jetzt ist die Sache klar.

Auf jeden Fall auch Danke für den Hinweis mit der "Heaptrc-Unit". Das werde ich mal
ausprobieren, klingt interessant.

"FreeAndNil" hatte ich auch schonmal für Delphi entdeckt, hier gabs aber nen Fehler ?!?
Werd ich auch nochmal ausprobieren.

Alles in allem: Viiiiiiieeeeeeeeeeelen Dank
mintpc

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Fragen zu "ObjektReferenz.Free" und "ObjektReferenz := n

Beitrag von Socke »

mintpc hat geschrieben:Frage 1: Ist es richtig, dass beim Aufruf von "free" die Referenze nicht unbedingt auf nil gesetzt wird?
Also, dass bei ObjektReferenz.Free nicht unbedingt (ObjektReferenz = nil) gelten muss, sondern
ObjektReferenz auch auf "Datenschrott" oder irgend etwas anderes zeigen kann?
Wenn das Objekt freigegeben wird, kann es die Referenz gar nicht auf nil setzen. Es weiß schlicht gar nicht, welche Referenz gemeint ist beziehungsweise von welcher Referenz es aufgerufen wurde.

Code: Alles auswählen

 
var
  o1, o2: TMyClass;
begin
  o1 := TMyClass.Create(nil);
  o2 := o1;
  o2.Free; // jetzt zeigen o1 und o2 auf Datenmüll
end;
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten