AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Frage zu FreeAndNil

Ein Thema von DelTurbo · begonnen am 19. Feb 2010 · letzter Beitrag vom 27. Feb 2010
Antwort Antwort
Seite 2 von 3     12 3      
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#11

Re: Frage zu FreeAndNil

  Alt 19. Feb 2010, 18:39
Aus: "FreeAndNil is often sign of wrong design - did anyone really read the blog?"
https://forums.embarcadero.com/threa...threadID=32623

Zitat:
Hence, Allen's assertion that, if calling FreeAndNil in a destructor
fixes your crash problems, there must be a design problem.
Frei übersetzt: "wenn man feststellt, dass man Crash-Probleme mit FreeAndNil im Destruktor in den Griff bekommt, dann ist das ein Hinweis auf ein Design-Problem".

Wenn man nun laufend solche FreeAndNil & Co. Absicherungen benötigt, weil die Entwickler sich nicht einig sind, wo das Problem - die Ursache der Crashs - liegt (oder es nicht verstehen), mag das ja gut sein um ein Softwareprodukt erst mal über Wasser zu halten. Es sollte aber dennoch versucht werden, die Ursache zu finden und durch geeignete Änderungen am Design in den Griff zu bekommen. Sonst rostet das Produkt unter dem Lack weiter vor sich hin, oder die vielen Tesafilm-Korrekturen die es zusammenhalten machen es immer schwieriger, es zu warten.

[man kann auch übermäßig defensiv programmieren und jede Zeile mit try ... except klammern (wobei im except Fall dann nichts getan wird). Das habe ich in Code schon gesehen und gefixt, der höllisch viele Exceptions erzeugte und daher entsprechend lahm lief]

Und, ja, es gibt Programmiersprachen die da robuster sind, aber manche von uns sind nun mal mit Delphi verheiratet

Cheers,
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#12

Re: Frage zu FreeAndNil

  Alt 19. Feb 2010, 18:53
http://blogs.embarcadero.com/abauer/2010/02/16/38916/
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#13

Re: Frage zu FreeAndNil

  Alt 20. Feb 2010, 14:34
So lange es in der Programmiersprache kein implizites Feature gibt das die Gültigkeit von Objektreferenzen automatisiert regelt hat FreeAndNil() eine Existenzberechtigung. Es lassen sich immer sinnvolle Anwendungsbeispiele für FreeAndNil() konstruieren wenn dies nicht so ist. Klar, man kann auch auf FreeAndNil() verzichten und baut dann eben umständlich einen aufwendigen und damit fehleranfälligen Mechanismus um auf FreeAndNil() verzichten zu können, zb. Notifications usw. Denoch bleibt am Ende die Erkenntis das FreeAndNil() für eine Sprache die keine automatische Bereinigung von Referenzen bietet eben eine Notwendigkeit ist.

Betrachtet man es so so wird auch ersichtlich wie im Grunde sinnlos diese Diskussion ist. Die saubere Lösung des Problemes ist die Änderung der Sprachfeatures, nur das halte ich für konstruktiv. Alleine schon die Konzentration, eg. Beschränkung der ganzen Diskussion auf FreeAndNil() innerhalb des Destructors, als Indiz für einen Designfehler, zeigt das diese Diskussion auf schwachen Beinen steht. Es ist unbestritten das auf Grund von Designfehlern die Problematik von FreeAndNil() im Destructor sich auftut, aber darauf ist das Problem nicht allgemein beschränkt und es berücksichtigt eben auch nicht das gerade Designfehler in der Produktion die meist gemachten Fehler mit den größten Konsequenzen sind. Dh. Designfehler wird es immer geben egal ob man FreeAndNil() und Destructoren benutzt oder eben eine Programmiersprache die auf Grund ihrer Konstruktion garnicht dieses spezielle Problem haben wird.

Ergo: ich bleibe bei meiner Aussage

1.) Designfehler vermeiden
2.) FreeAndNil() benutzen, da man Designfehler nie zu 100% ausschließen kann
3.) wenn erforderlich mit bedingten Assertions() arbeiten um die Fehlersuche zu verbessern

Diese Arbeitsweise wird uns aufgezwungen da die benutzte Programmiersprache eben Defizite hat.

Designfehler kann man allein schon auf Grund der flexiblen Zielsetzungen die in der Praxis vorkommen garnicht ausschließen. Ich möchte den Auftraggeber sehen der nach ein Jahr Entwicklung und nach geänderten Anforderungen an die Software, die eben auch grundsätzliche Änderungen im Design bedingen, nun freiwillig einsieht das oft die komplette Software von Grund auf neu entwickelt werden muß, also nochmals ein Jahr an Entwicklung nötig wird. Und mir soll keiner kommen das man dann dem Auftraggeber verklickern soll auf seine Änderungswünsche nicht eingehen zu können. Man wird eher ziemlich schnell weg vom fenster sein und keine weiteren Aufträge mehr bekommen.

Man kann also über den Idealfall diskutieren wie man möchte die Praxis kennt den Idealfall garnicht, und wir Entwickler sollten Pragmaten und keine Dogmaten sein.

Gruß Hagen
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#14

Re: Frage zu FreeAndNil

  Alt 20. Feb 2010, 15:02
FreeAndNil sollte man schon bevorzugt benutzen, jedoch sollte man es nicht alls Allheilmittel betrachten.
D.h. wenn es eine Zugriffsverletzung gibt, weil man xy.Free benutzt und nach FreeAndNil plötzlich alles wunderbar funktioniert, dann sollte man es nicht dabei belassen.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#15

Re: Frage zu FreeAndNil

  Alt 26. Feb 2010, 11:21
Versteh ich nicht, bzw. das ist unlogisch.

zwei Szenarien:

1.) Objekt.Free lösst Exception aus:

Wird stattdessen mit FreeAndNil(Objekt) gearbeitet wird es denoch diese Exception geben. Ich wüsste nicht das FreeAndNil() intern Exceptions abfängt. So oder so wird man also eine Exception bekommen, wenn sie in .Free auftritt dann auch in FreeAndNil(). Der Fall das Objekt = nil ist mal aussen vorgenommen da FreeAndNil() identisch zu if Objekt <> nil then Objekt.Free ist.

2.) nach Objekt.Free wird Exception ausgelösst aber bei FreeAndNil() nicht mehr.

Sicheres Indiz dafür das das Program im späteren Ablauf nochmals auf Objekt zugreift obwohl es zerstört wurde. Der Programmierer hat aber schon Vorsorge beim Zugriff auf Objekt mit Assigned(Objekt) getroffen.

Damit lösst FreeAndNil() definitiv und sauber das entstandene Problem. Mehr noch, da FreeAndNil() die Objektreferenz vor dem .Free Aufruf erstmal in eine temp. Variable kopiert und sofort die Referenz auf nil setzt, vermeidet FreeAndNil() eine Kaskade von Fehlern beim Aufruf von .Free. Es ist also sicherer als das Equivalent von

Delphi-Quellcode:
if Objekt <> nil then
begin
  Objekt.Free;
  Objekt := nil;
end;
Wenn nämlich Objekt.Free eine Exception auslösst dann wird die Variable nicht mehr auf nil gesetzt. Das macht FreeAndNil() anders. Eigentlich müsste die Funktion NilAndFree() heissen.

Welche anderen Fehlerquellen für Objekt.Free im Unterschied zu FreeAndNil() sollte es noch geben ?

Alle anderen Exceptions können wir ausklammern und könnten Designfehler sein, richtig, aber sie haben nichts mehr mit Objekt.Free und FreeAndNil() im Zusammenhang gesehen zu tuen.

Ergo: dämliche Diskussion da es keinen Bezug von FreeAndNil() im Unterschied zu Objekt.Free zu einem Designfehler gibt. Denn wenn Designfehler die Ursache des Problems sein sollten dann werden sie mit FreeAndNil() genauso wenig gelösst wie mit einfachem Objekt.Free. Auch wenn dann bei FreeAndNil() erstmal scheinbar eine spezifische Exception nicht mehr auftritt so ist denoch das Program garnicht darauf vorbereitet mit Objektrefernezen die nil sind umzugehen und wird später eben dort Exceptions auslösen, eben Designfehler. Es ist also irrelevant ob man Objekt.Free im Vergleich zu FreeAndNil() betrachtet, der Designfehler wäre die Ursache und daran muß man arbeiten.

Nun, wenn das die Kernaussage der ganzen Diskussion sein sollte dann sage ich nur -> trivial, das sollte jeder halbwegs logisch denkende Mensch sofort begriffen haben. Beseitige die Ursache des Problems statt an den Symptomen rumzudoktern (naja, unsere Prolitiker machen das ja nur so).

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Frage zu FreeAndNil

  Alt 26. Feb 2010, 11:32
Zitat:
Delphi-Quellcode:
if Objekt <> nil then
begin
  Objekt.Free;
  Objekt := nil;
end;
Eigentlich reicht ja
Delphi-Quellcode:
Objekt.Free;
Objekt := nil;
Dieses ( if Assigned(Objekt) then )
if Objekt <> nil then wird ja in .Free geprüft.

FreeAndNil prüft dieses auch nicht mehr, da es inter wiederum .Free aufruft, welches das ja prüft.
(aber im Prinzip isses ja egal)



Aber das mit der "Kaskade" stimmt schon, da durch FreeAndNil einfach sichergestellt ist, daß die Objekt-Variable auf nil gesetzt wird.
Delphi-Quellcode:
// Objekt := nil; >> wird sicher auf nil gesetzt
// Objekt.Free; >> exception

Temp := Objekt;
Objekt := nil; >> wird sicher auf nil gesetzt
Temp.Free; >> exception
Hier ist dieses eben nicht sichergestellt, wie negaH es eben so schön erklärte
Delphi-Quellcode:
Objekt.Free; >> exception
Objekt := nil; >> wird NICHT mehr auf nil gesetzt,
                >> da der Programmablauf vorher abbricht
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#17

Re: Frage zu FreeAndNil

  Alt 26. Feb 2010, 12:21
Zitat von Luckie:
Ich habe mir aber trotzdem angewöhnt FreeAndNil zu benutzen, dann ist man immer auf der sicheren Seite.
Luckie hat da schon recht. Egal wo, ich verwende auch FreeAndNil, obwohl man die SysUtils-Unit dann einbinden muss. Ich weiß, dass die Referenz auf das Objekt danach auf jeden Fall nil ist und zudem sollte das Objekt im Normalfall auch freigegeben sein.
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#18

Re: Frage zu FreeAndNil

  Alt 26. Feb 2010, 13:21
Zitat von negaH:
Auch wenn dann bei FreeAndNil() erstmal scheinbar eine spezifische Exception nicht mehr auftritt so ist denoch das Program garnicht darauf vorbereitet mit Objektrefernezen die nil sind umzugehen und wird später eben dort Exceptions auslösen, eben Designfehler.
Soweit ich es verstanden habe, geht es nicht um spezifische, sondern um 'unspezifische', d.h. irreguläre Exceptions, von denen man nicht auf die eigentliche Fehlerursache schliessen kann, seltsame Crash-Meldungen also. Es geht in dem erwänten Newsgroup-Thread nur um Crashs, die durch Verwendung von FreeAndNil im Destruktor 'unterdrückt' werden.
Michael Justin
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#19

Re: Frage zu FreeAndNil

  Alt 27. Feb 2010, 10:03
@himitsu:

Ist mir bewusst das .Free intern Self auf nil prüft, das muß aber nicht für selber geschriebene Destruktoren gelten. Zudem bezog sich mein Assigned(Objekt) ja eher auf die anderen Zugriffe auf solche Objektreferenzen die auch nil sein könnten.

@Michael:

Genau so habe ich das auch heraus gelesen und exakt deswegen bezweifle ich die Sinnhaftigkeit dieser Diskussion. Denn FreeAndNil() im Vergleich zu native .Free hat nichts mit den Fehlerursachen geschweige denn mit der Art&Weise der Programmierung noch Fehlersuche zu tun.

Die letzendliche Schlußfolgerung die ein unbedarfter Entwickler aus dieser Diskussion ziehen würde ist doch das man mit FreeAndNil() vorsichtig sein sollte, und das ist falsch, egal in welchem Kontext man FreeAndNil() statt .Free benutzt.

Falls es designtechnische Probleme mit .Free und FreeAndNil() gibt, die schlußendlich deren Existenzberechtigungen betreffen, dann kann das nur ein Problem der Feature der Programmiersprache sein. Dann wäre die Diskussion auch sinnvoll.

Die einzige Legitimation für FreeAndNil() statt einfachem .Free ist eben der Fakt das FreeAndNil() vor der Freigabe des Objektes die Objektreferenz auf nil zurücksetzt, neben dem Punkt das es ein Einzeiler im Source ist.

Gruß Hagen

PS: benutzt man FreeAndNil() statt .Free und hat den Designfehler gemacht das man im restlichen Program immer davon ausgeht das die Objektreferenz garnicht nil sein darf dann wird man Zugriffsschutzverletztungen bekommen die als Addresse 0x0000000?? angeben statt irgendeine Speicheradresse. Das ist für einen erfahrenen Entwickler der sofortige Hinweis das man irgendwo im Source auf ein "nil-Objekt" zugreift, ergo wesentlich konstruktiver für die Fehlerbeseitigung. Betrachtet man nun in diesem Zusammenhang noch den Fakt das die Speicherverwaltung freigegebene Speicherbereiche gleicher Größe sofort wieder verwendet dann kann es ohne FreeAndNil(), und späteren fehlerhaftem Zugriff auf ein nicht mehr existentes Speicherobjekt, dessen ehemaliger Speicherbereich nun schon längst wieder für ein anderes Objekt benutzt wird, noch zu viel wilderen und schwerer zu findenen Fehlern kommen. Ein weiteres Argument pro FreeAndNil().
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#20

Re: Frage zu FreeAndNil

  Alt 27. Feb 2010, 13:15
Zitat von negaH:
Die einzige Legitimation für FreeAndNil() statt einfachem .Free ist eben der Fakt das FreeAndNil() vor der Freigabe des Objektes die Objektreferenz auf nil zurücksetzt, neben dem Punkt das es ein Einzeiler im Source ist.
Warum soll eine Referenz auf ein Objektfeld *in einem Destruktor* auf nil gesetzt werden? Denn schliesslich soll danach kein Zugriff mehr auf das Feld erfolgen. Wenn dennoch eine Methode auf dieses Feld zugreifen will, dann ist das das im Thread gemeinte 'bad design'.

Wenn bei Verwendung von FreeAndNil() im Destruktor (nur darum geht es!) der nachfolgende Zugriff auf das freigegebene Feld an anderen Stellen mit "if Assigned()" abgesichert wird, wird keine AccessViolation ausgelöst. D.h. man verwendet zwei für sich genommen sinnvolle Konstrukte zur 'defensiven' Codierung, die zusammen dann aber einen Fehler verdecken.
Michael Justin
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 01:14 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