![]() |
Probleme mit TObject.Free
Hallo zusammen erstmal!
Ich hätte da mal en kleines Problem und hoffe hier kann mir jemand weiterhelfen :-D Ich habe ein eigenes Objekt nach folgendem Schema definiert:
Delphi-Quellcode:
das Objekt lässt sich mit Create herstellen und mit Free zerstören
type
TMyObj = class(TObject) public constructor Create(Param:String); destructor Destroy; override; private procedure DoSomething; end;
Delphi-Quellcode:
So, nun das Problem:
procedure Foobar;
var MyObj: TMyObj; begin try MyObj := TMyObj.Create('Oi!'); MyObj.DoSomething; [...] finally MyObj.Free; end; end; Ich habe festgestellt, dass ein erneuter Aufruf von .Free - also wenn das Object bereits mit .Free zerstört wurde - zu einem Exception Error führt (Memory Access Violation). So weit ich es verstanden hab, sollte das Objekt doch nach dem ersten .Free aufruf zerstört und somit wieder nil sein. Ein zweiter Aufruf von .Free sollte dies erkennen und keinen Fehler verursachen. Das is doch der Grund, warrum ich .Free anstatt .Destory aufrufe, oder? Iregndwie schein meint Objekt aber nach dem Zerstören durch .Free nich nil zu werden. Ergo: Der Speicher wurde nich korrekt freigegeben. Wo steckt bloß der Fehler ??? Oder hab ich da was falsch verstanden? |
Re: Problem with TObject.Free
Hallo
.free setzt das object nicht automatisch auf Nil, das mußt du selbst tun. Dafür gibt es
Delphi-Quellcode:
Mfg Frank
FreeAndNil(myobject);
|
Re: Probleme mit TObject.Free
Cool, danke für die superschnelle Antwort :-D
Warrum steht sowas nich in der Anleitung ??? Sollte ich dann also immer FreeAndNil(MyObj) anstatt MyObj.Free benutzen, damit der Speicher korrekt freigegeben wird? |
Re: Probleme mit TObject.Free
Bin gerade auch mit so was beschäftigt. Versuche das hier mal :
Delphi-Quellcode:
Allerdings wäre interessant zu wissen, wo das Objekt herkommt / rzeugt wird.
Abject.Destroy;
Aject := nil; |
Re: Probleme mit TObject.Free
@Hansa:
Du solltest .Free anstatt .Destroy aufrufen, so viel is sicher. Aber scheint so, als ob du das Objekt hinterher noch manuell auf nil setzten musst! Ich denke am besten isses dieses FreeAndNil(TObject) zu benutzen, wie es Keldorn vorgeschlagen hat... |
Re: Probleme mit TObject.Free
Hab grad en Beispiel gefunden. Schaut mal hier:
![]() |
Re: Probleme mit TObject.Free
Zur Erklärung:
Myobj.free zerstört das Objekt und gibt den Speicherplatz frei. MyObj := nil setzt die Referenz auf das Objekt zurück, denn Myobj ist nicht das Objekt sondern ein Zeiger darauf. |
Re: Probleme mit TObject.Free
Okay, soweit verstanden.
Aber wozu is eine Referenz auf ein zerstörtes Objekt gut, so wie es .Free hinerlässt? Das führt doch höchstens zu Exceptions, z.B. wenn man nochmal .Free benutzt! Also werde ich dann zukünftig FreeAndNil(TObject) anstatt TObject.Free benutzen, um Probleme zu vermeiden. |
Re: Probleme mit TObject.Free
Hallo Lord,
das dangling pointer problem entsteht erst durch globale Zeigervariablen. Je mehr solche globalen Variablen du eliminierst, desto bedeutungsloser werden deine Maßnahmen zur Eindämmung möglicher Programmschäden - am Ende kannst du wieder rein objekt-orientiert mit der Methode Free() arbeiten. Grüße vom marabu damned dropped characters |
Re: Probleme mit TObject.Free
Das Problem lässt sich aber in meinem Fall nich so ohne weiteres Umgehen, da ich teilweise nich vorhersagen kann, ob das Objekt bereits zerstört wurde. Natürlich gäbe es da auch wege, das Problem anders zu lösen. Aber FreeAndNil(Obj) scheint doch ne ganz elegante Lösung zu sein!
|
Re: Probleme mit TObject.Free
Hallo
wieso weißt du nicht, ob das Object nicht schon freigegeben wurde? Wenn du so vorgehst, wie in deinem Bsp, kann doch gar nix passieren. Ich verwende eigentlich nie FreeAndNil und hab trotzdem keine Probleme mit der doppelten Freigabe. Mfg Frank |
Re: Probleme mit TObject.Free
So schön einfach wie im Beispiel sieht die Sache leider nich aus :?
Mein Problem war ja auch hauptsächlich, dass ich dachte mein Objekt müsste wieder nil sein, nachdem ich .Free benutz hab. Weil das ja nich so war, hab befürchtet, ich hätte was vergessen bzw. falsch gemacht. Vorallem was den destructor angeht. Aber wenn das normal is, dass .Free einen "dangling pointer" hinterlässt, is ja alles soweit okay. Muss man ja nur wissen, dann kann man damit umgehen. In der Anleitung is das leider mit keinem Wort erwähnt. Da steht ja extra man soll .Free statt .Destroy nehmen, damit man nich darauf achten muss, ob das Objekt bereits nil is. Vondaher wäre es schlüssig gewesen, wenn das Objekt nach .Free wieder nil wäre. Is halt nich so... Also noch ma danke für die Hilfe :hi: |
Re: Probleme mit TObject.Free
Zitat:
|
Re: Probleme mit TObject.Free
Edit: Vergiss es, war Quatsch...
Gruß, teebee |
Re: Probleme mit TObject.Free
Mein Posting hat wohl keiner gelesen. 8) Der Tip kommt von Borland selber ! Destroy und auf NIL setzen ist die Methode, die wasserdicht sein soll. Allerdings habe ich gemerkt, daß egal wie, das alles keine grossen Auswirkungen hat.
|
Re: Probleme mit TObject.Free
Wieso Destroy+Nil "wasserdichter" sein soll als Free+Nil oder FreeAndNil ist mit nicht klar. Free ruft auch nur Destroy auf, prüft vorher aber noch auf self<>nil und verhindert so eine AV, die man sonst bekäme, wenn self schon nil ist.
Gruß, teebee |
Re: Probleme mit TObject.Free
Hallo Hansa,
Zitat:
marabu |
Re: Probleme mit TObject.Free
@Hansa:
Also, dass man TObject.Free und eben *nicht* TObject.Destroy aufrufen soll, steht doch explizit in der offiziellen Delphi Hilfe-Datei. Macht ja auch Sinn, weil - wie schon oft gesagt - TObject.Free auch nichts anderes tut als TObject.Destroy aufzurufen. Der einzige Unterschied: TObject.Free verhindert, dass ein TObject = nil einen AV Error verursacht. Von daher is TObject.Free die sichere Methode! Aber TObject wird dabei niemals nil, weder bei TObject.Free noch bei TObject.Destroy. Ob man das "zerstörte" TObject nun als "dangling pointer" lässt oder manuell auf nil zurücksetzt, is ja nur dann interessant, wenn man zu einem späteren Zeitpunkt nochmal auf den Pointer zugreift. Also z.B. wenn man noch mal Object.Free ausführt, ohne vorhersagen zu können, ob das Objekt bereits "zerstört" wurde. Ansonsten is das grad egal... Ob man nun FreeAndNil(Object) oder Object.Free plus Object=nil benutzt kommt auf's gleiche raus. Aber FreeAndNil() is wohl die elegantere Lösung... Zitat:
|
Re: Probleme mit TObject.Free
@Hansa: es ist mir völlig neu, dass man .Destroy statt .Free benutzen soll!
|
Re: Probleme mit TObject.Free
Delphi-Quellcode:
:roll:
unit System
[...] procedure TObject.Free; begin if Self <> nil then Destroy; end; |
Re: Probleme mit TObject.Free
@lord-mulder: Dass '.Free' nichts anderes macht, als auf 'nil' zu testen und dann das Objekt per '.Destroy' zerstört, war mir auch klar! :mrgreen:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:43 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