AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Warum wird TObject.Free nicht gleich auf nil gesetzt

Warum wird TObject.Free nicht gleich auf nil gesetzt

Ein Thema von Hobbycoder · begonnen am 8. Mai 2020 · letzter Beitrag vom 8. Mai 2020
Antwort Antwort
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#1

Warum wird TObject.Free nicht gleich auf nil gesetzt

  Alt 8. Mai 2020, 00:24
Ich habe gerade eine ganze Zeit mit der Fehlersuche zugebracht.
Der Fehler war natürlich ganz trivial. Ich habe irgendwo ein Object mit Free freigegeben und später im Code auf NIL geprüft, was natürlich nicht funktionierte. Erst ein FreeAnNil() funktionierte dann wie erwartet. Kurzer Blick die System-Unit, und es war klar.
Delphi-Quellcode:
destructor TObject.Destroy;
begin
end;

procedure TObject.Free;
begin
// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
  if Self <> nil then
    Destroy;
{$ENDIF}
end;
Jetzt werden sicher einige von euch die Hände über dem Kopf zusammenschlagen.

Daher bitte auf diese Frage konzentrieren: Warum ist das so?
Wenn ich ein Object per Free freigebe ist doch im Grund klar, das ich das Object nicht mehr benötige. Warum wird es dann nicht gleich auf nil gesetzt?
Gibt es Fälle, in den sowas sinnvoll ist? Oder ist das Compilertechnisch einfach nur nicht machbar, dass sich das Object selbst auf nil setzt?
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Warum wird TObject.Free nicht gleich auf nil gesetzt

  Alt 8. Mai 2020, 00:46
Weil du genau genommen Objekte nicht auf nil setzen kannst. Du kannst Variablen die auf Objekte verweißen auf nil setzen.
Und genau darin besteht das Problem. Du kannst 10 verschiedene Variablen haben die alle auf das selbe Objekt verweisen.
Aber weder der Compiler noch sonst wer weiß wer oder was evtl. noch Referenzen auf ein Objekt hat um die entsprechenden Variablen beim Freigeben auf nil setzen zu können.
FreeAndNil ist im Grunde nichts anderes als

Delphi-Quellcode:
objVar.Free;
objVar := nil;
Aber bei FreeAndNil musst du auch explizit die Variable übergeben die du dann auf nil setzen willst.
Mal ein Beispiel:

Delphi-Quellcode:
objVar1 := TObject.Create;
objVar2 := objVar1;
objVar3 := objVar1;

FreeAndNil(objVar1);
Das Objekt hinter objVar1 wird freigegeben und objVar1 ist nil.
objVar2 und objVar3 sind aber immernoch <> nil und zeigen auf den Speicherbereich wo das Objekt vorher war.
Ein Zugriff oder sogar ein weiterer Aufruf von Free oder FreeAndNil auf objVar2 oder objVar3 führt zu einer Zugriffsverletzung.

Aber das Grundverständnisproblem was du hast ist, dass die Variable nur eine Referenz (einen Pointer) auf das eigentliche Objekt im Speicher enthält.
Es macht logisch gesehen daher gar keinen Sinn davon zu sprechen dass sich das Objekt selbst auf nil setzt.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Warum wird TObject.Free nicht gleich auf nil gesetzt

  Alt 8. Mai 2020, 05:41
Hallo,
schön erklärt als ein Grund.

Der zweite Grund:
Das Nil-Setzen ist ein zusätzlicher Befehl,
der oft einfach nicht notwendig ist,
wenn das Objekt zum Beispiel in einer Methode erzeugt,
und nach der Nutzung wieder freigegeben wird.
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.122 Beiträge
 
Delphi 12 Athens
 
#4

AW: Warum wird TObject.Free nicht gleich auf nil gesetzt

  Alt 8. Mai 2020, 09:15
Ja, jemand kam auf die geniale aublöde Idee ein DisposeOf zu erfinden, anstatt das neue "Verhalten" ins Free reinzubauen.

Echt geil, denn damit gibt es wieder einen Grund, weswegen Code nicht mehr sooooo abwärtskompatibel wird, wie man früher mal so stolz verkündet hat.
Es ist inzwischen oftmals eh unmöglich geworden ohne IFDEFs noch einen platformübergreifenden Code zu schreiben, der auch in älteren Delphis läuft, selbst wenn man nur Grundfunktionen der RTL benutzt.
Und eine Unit die mit FMX und VCL klar kommt, bzw. z.B. ein BitMap oder Canvas bemalt, aber jeder einen anderen Typ benutzt ... wie soll das gehen, wenn man in der Unit nicht prüfen kann, was es von Beidem genutzt wird.


Nja, Free ist eine "normale" Methode und das bekommt nur den Wert, aber nicht die Adresse der Variabble rein, somit kann es nichts auf NIL setzen.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PosEx im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Warum wird TObject.Free nicht gleich auf nil gesetzt

  Alt 8. Mai 2020, 10:04
Hallo,
Zitat:
wie soll das gehen, wenn man in der Unit nicht prüfen kann, was es von Beidem genutzt wird.
IFDEF ?

*druck*
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.122 Beiträge
 
Delphi 12 Athens
 
#6

AW: Warum wird TObject.Free nicht gleich auf nil gesetzt

  Alt 8. Mai 2020, 11:31
Ja, und auf was willst du prüfen?
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PosEx im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#7

AW: Warum wird TObject.Free nicht gleich auf nil gesetzt

  Alt 8. Mai 2020, 13:05
Okay, danke für eure Erklärungen. Jetzt ist mir klar, warum das nicht geht.

Also kann ich mir das so vorstellen, dass das .Free letztlich (nicht nur) für den MemoryManager da ist, um ihm mitzuteilen, dass der reservierte Speicher nicht mehr benötigt wird, und das :=nil lediglich die Zeiger des Object auf 0, -1, oder was auch immer, setzt.

Klar, dass das Object selbst nicht weiß, in welcher Variable sein Zeiger gespeichert ist, ist irgendwie logisch.
Und wenn ich so überlege, macht das durch aus Sinn, Zeiger auf nil setzen zu können ohne das Object zu zerstören.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Warum wird TObject.Free nicht gleich auf nil gesetzt

  Alt 8. Mai 2020, 13:18
Zu dem Thema kannst Du Dir auch mal "automatische Referenzzählung bei Interfaces" ansehen.
Ich arbeite nahezu nur noch damit. Hat natürlich auch seine Nachteile, mit denen man dann leben muss.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz