![]() |
Delphi-Version: 5
Webinar FreeAndNil
Hallo zusammen,
für alle diejenigen welche Formel 1 Rennen schauen weil es dort so fürchterliche Unfälle geben kann, und das sind ja wohl die meisten :stupid: gibt es hier ein schönes ![]() Das wird wohl wieder ein Hauen und Stechen auf dem Feld der Ehre geben, ohne echte Gewinner und Verlierer oder einen Pokal, wie in der Realität eben :-D Aber im Ernst: Bei der Registierung wird auch abgefragt wer wie oft FreeAndNil bzw. if Assigned() benutzt, das finde ich sehr interessantes Survey, das hoffentlich im Webinar enthüllt wird. Also ich hoffe dass da dann Alle mitmachen um mal einen schönen Überblick zu bekommen. |
AW: Webinar FreeAndNil
Assigned macht weder bei Free noch FreeAndNil Sinn, weil es intern schon abgefragt wird.
Wer Assigned vor einem Free/FreeAndNil benutzt weiß das entweder nicht oder programmiert nach Aberglaube oder Paranoia. Ansonsten halte ich es so, dass ich FreeAndNil für Felder innerhalb einer Klasse nutze (oder globale Variablen) und Free für lokale Variablen die im selben Methodaufruf erstellt und wieder freigegeben werden. |
AW: Webinar FreeAndNil
jupp, genau so.
Nur dasss ich meistens (noch) die Felder in Klassen wie lokale Variablen betrachte, also eher davon ausgehe, dass nach dem Destroy niemand diese Variablen benutzen wird und somit dort nur .Free mache. (in Punkto Fehlersuche kann dort aber ein NIL dann doch nicht schaden, weil ja doch noch wer die nun ungültige Objektvariable nutzen und auf den eventuell immernoch vorhanden ehemaligen Feld-Speicher zugreift) |
AW: Webinar FreeAndNil
Ich mache es auch so, wie Neutral General.
Ansonsten habe ich die Frage mit "if assigned" nicht zwingend darauf bezogen, dass es vor Free/FreeAndNill steht, sondern eher allgemein. Dann stellt sich nämlich tatsächlich die Frage, wann Free reicht und man unbedingt ein FreeAndNil nehmen sollte. Assigned setzt schließlich voraus, dass nicht mehr referenzierte Objekte nil sind. Und das kann irgendwo im Source passieren. |
AW: Webinar FreeAndNil
Wenn man nix interessantes zu berichten hat, dann macht man ein Webinar zu so nem Quatsch :lol:
|
AW: Webinar FreeAndNil
Ist gerade Sommerloch?
|
AW: Webinar FreeAndNil
zu viel Corona, Krieg, Öl, Hühnergrippe, Schweinegrippe, lecker Pferdefleisch usw. ... hat sich nun alles abgenutzt.
Hey, die "Currywurst" (deutsche Schreib- und Sprachweise) hat es nun ins englische Dictionary geschafft. Und jetzt versucht man auch noch das Currywurst-Smiley beim Unicode-Consortium zu beantragen. (das falsche deutsche Wort "Booster-Impfung" hatten wir bereits erfolgreich in viele andere englischsprachige Länder exportiert) |
AW: Webinar FreeAndNil
Ok, dann bin ich wohl der Einzige den das Ergebnis des Surveys interessiert :pale:
Naja Ok, das Thema ist vielleicht schon zuuuuu lange durch bei allen Beteiligten, so dass die konkrete Nutzung in der Praxis keinen mehr interessiert. |
AW: Webinar FreeAndNil
Hätte es die Umfrage ohne Anmeldung gegeben, hätte ich das als FreeAndNil+Assigned:love:er mal kurz durchgeclickt. Aber so wird das nix.
Allerdings finde ich es schon ein bisschen seltsam das sich so viele Leute daran abreiben/aufreiben wollen. Als Delphianer räumt man ordentlich weg, was man hingeräumt hat. Was gibt es darüber zu lamentieren? |
AW: Webinar FreeAndNil
Zitat:
|
AW: Webinar FreeAndNil
ROFL...
Kaum hatte Jim McKeeth das Thema im MVP Channel gepostet, ging die Diskussion schon los... Keine Ahnung ob das Webinar jemanden etas bringt, aber wer sehen will, wie unterschiedlich die Meinungen unter den MVP's sind ist eingeladen... Wird sicherlich lustig... Grüsse Mavarik |
AW: Webinar FreeAndNil
Zitat:
|
AW: Webinar FreeAndNil
Zitat:
|
AW: Webinar FreeAndNil
Na ja dein Footer himitsu ... :-D
Wenn Delphianer wirklich so sind. Schade dass man Kollegen hat die keine Delphiander sind aber Sourcecode in Delphi machen :twisted: |
AW: Webinar FreeAndNil
Zitat:
Zitat:
|
AW: Webinar FreeAndNil
Zitat:
Ich finde, dass es sowohl Anwendungsfälle gibt, an denen FreeAndNil sehr viel Sinn macht, als auch solche, bei denen es keinen / wenig Sinn macht. |
AW: Webinar FreeAndNil
Zitat:
Es ist also eine Sünde einfach FreeAndNil zu verwenden anstatt ordentlich zu programmieren und sicherzustellen das man nicht auf Objektreferenzen zugreift deren Objekte schon freigegeben sind. So ganz sachte verstehen ich den Salat! Verwender von FAN sind also zu faul um ordentlich zu programmieren. Das ist jedenfalls die Meinung der FAN Gegner/Verweigerer. Das macht mich Sprachlos. FAN hat den Vorteil das ich gegenchecken kann ob das Objekt weg ist. Ich kann also Objekte freigeben, und deren Referenzzustand "freigegeben" als Schalter verwenden. Ich sehe mich dadurch nicht als Faul, sondern als Gewissenhaft an. |
AW: Webinar FreeAndNil
Nja, im Notfall kann man immer FreeAndNil machen, was nahezu nie verkehrt ist.
Während bei einem .Free das nötige Zurücksetzen der Variable eventuell fehlen könnte. (z.B. für nachfolgende if-Assigned) Und
Delphi-Quellcode:
könnte zwar richtig sein, aber wenn es im Free knallt, dann würde das NIL nicht mehr ausgeführt.
x.Free;
x := nil; Zu
Delphi-Quellcode:
hat man oft keine Lust, was man aber mit FreeAndNil (eigentlikch NilAndFree) viel "einfacher" haben würde.
try
x.Free; finally x := nil; end; Und über ein Property oder ein Function-Result zu Löschen, da geht nur Free. Für FreeAndNil müsste man es erst in eine Variable umkopieren. (aber nur sinnvoll, wenn sich das Objekt da drüben auch selbst deregistriert/entfernt) Krank / unverständlich empfinde ich aber, dass man Assigned bei Property/Result nicht direkt nutzen kann. Wieso eigentlich nicht? (ein <>NIL als Ersatz ginge zwar, aber ist schon bissl inkonsistent, wenn sonst überall anders mit Assigned) |
AW: Webinar FreeAndNil
Zitat:
|
AW: Webinar FreeAndNil
Von den ganzen Pro-Argumenten finde ich das Proaktiv-In-Der-Zukunft Argument eigentlich am Schönsten:
In einer Basis-Klasse, die mal abgeleitet werden könnte, hilft FAN im Destruktur den Zugriff auf interne Felder abzusichern, falls die Klasse zufällig mal abgeleitet wird und dabei jemand anderes diese falsch benutzt und versucht nach Destroy drauf zuzugreifen. So oder so ähnlich. Ist schön vorrausschauend gedacht, gefällt mir, aber ich fürchte es bleibt dabei: Man braucht es eigentlich nicht wirklich wenn man das Klassen-Design gut ausgelegt hat. |
AW: Webinar FreeAndNil
Zitat:
|
AW: Webinar FreeAndNil
Wenn ich eine lokale Objekt-Variable habe, dann wird die ja auf dem Stack abgelegt. Erzeuge ich die dann und gebe die wieder frei (ohne nil Zuweisung), dann bleibt der Stack mit dem nicht mehr gültigen Zeiger bestehen. Rufe ich dann die Funktion nochmal auf, könnte ich den gleichen Speicherplatz nochmal zugewiesen bekommen auf dem Stack und ich habe im ASM Code nichts gesehen, welches die lokale Variable automatisch vorinitialisiert, also rein technisch könnte sie mit einem ungültigen Pointer belegt sein. Deswegen nutze ich da immer FreeAndNil.
Oder sehe ich das falsch ? Hat sich da mittlerweile was geändert ? |
AW: Webinar FreeAndNil
Zitat:
|
AW: Webinar FreeAndNil
Ja. Außerdem ist das Problem dann nicht nur bei "Rufe ich dann die Funktion nochmal auf ..." sondern auch beim ersten mal kann die Variable dann mit falschem belegt sein.
|
AW: Webinar FreeAndNil
Außerdem gilt das ja nicht nur für Objekt-Instanzen sondern auch für alle anderen lokalen Variablen. Konsequenterweise müsste man die dann beim Verlassen auch alle auf 0, nil oder sonstwas setzen, damit sie bei einem möglichen nächsten Aufruf dedizierte Werte erhalten. Dann vielleicht doch besser am Anfang initialisieren.
Ubrigens: Strings, Interfaces und sonstwie gemanagete Typen werden als lokale Variablen sehr wohl initialisiert. Es macht aber dann auch nichts wenn man es selbst nochmal macht. |
AW: Webinar FreeAndNil
Zitat:
Aber das was du beschreibst war auf der anderen Seite auch nie ein Problem. Wie Uwe schon sagte: Du musst lokale Variablen sowieso initialisieren, wenn du keinen Datenmüll in deinen Variablen stehen haben willst. Das gilt auch schon beim aller ersten Aufruf der Funktion - Der Stack wurde vorher bereits von etlichen anderen Funktionen genutzt wodurch deine lokale (Objekt-)Variable bereits beim ersten Aufruf der Funktion mit großer Wahrscheinlichkeit einen Pointer ins Nirvana enthält, weil an der Stelle vllt. zufällig eine Schleifenvariable einer anderen Funktion liegt oder eine Rücksprungadresse oder sonst irgendwas anderes. |
AW: Webinar FreeAndNil
Zitat:
Ein Resize vom Form das auf etwas zugreift oder ein Itemindex der noch belegt wird und und und! In so einen Fall die fStringList mit FreeAndNIL zu löschen und überall Assigned vor der Verwendung zu testen, verhindert einfach eine exception ohne lange zu überlegen, was alles noch passiert. Grüsse |
AW: Webinar FreeAndNil
[QUOTE=Mavarik;1508097]
Zitat:
|
AW: Webinar FreeAndNil
Zitat:
|
AW: Webinar FreeAndNil
Zitat:
Mit FreeAndNIL ist es "egal". Zitat:
Wäre nicht das 1. mal, dass ich hier von der Reihenfolge überrascht wurde. |
AW: Webinar FreeAndNil
Zitat:
Ich habe so oft Fehler, die auf unterschiedlichen timings basieren, einfach schon weil jeder Nutzer einen anderen Rechner hat und unterschiedlich schnellen DB/Netzwerkzugriff. Oder selbst USB Geräte sich unterschiedlich verhalten. Selbst nach einem Windows-Patchday kann es sein das sich was anders verhällt. Da arbeite ich lieber paranoid mit FreeAndNil. |
AW: Webinar FreeAndNil
Zitat:
|
AW: Webinar FreeAndNil
Zitat:
FreeAndNil kann grundsätzlich nicht schaden, aber sollte in den aller wenigsten Situationen notwendig sein. |
AW: Webinar FreeAndNil
Zitat:
Das gilt natürlich nicht für Stellen, an denen nil explizit als Flag für "nicht zugewiesen" verwendet wird, das also so gedacht ist. Dann darf man es natürlich nirgends an solchen Stellen weglassen oder vergessen (was bei mehreren Personen, die am Quelltext arbeiten, auch problematisch sein kann). Das klang jetzt aber nicht so, als ob das gemeint ist. |
AW: Webinar FreeAndNil
Zitat:
Wenn man nicht weiss aber auch wenn man weiss in welcher Reihenfolge Events kommen - entweder a) erzeugt man das Objekt in der Methode und gibt die abgesichert durch try finally in der Methode auch wieder frei. b) Wenn man die Daten übergreifend benötigt, dann erzeugt man das Objekt bei der Erzeugung des Forumlars und gibt es bei der Zerstörung des Formulars wieder frei. c) benutzt man (so wie ich meistens) nur Objekte mit Referenzählung. :-D Nachschlag: 1. Bei der Benutzung von TStringlist "liegt ein Defekt in der Architektur" vor - meistens. 2. Bei 50 Komponenten auf einem Form "liegt ein Defekt in der Architektur" vor - meistens. Zitat:
|
AW: Webinar FreeAndNil
Zitat:
|
AW: Webinar FreeAndNil
Das finde ich in der Tat auch eine gewagte Aussage.
|
AW: Webinar FreeAndNil
Hm, im Erklären bin ich recht schlecht, aber ich versuchs.
Vorab, das "meistens" ist in dem Fall vielleicht doch zu hoch gegriffen. Bei unserer Applikation gilt es auf jeden Fall, auch eher wenn es um die FreeAndNil-Problematik geht. Ein string ist (vereinfacht) recht allgemein eine Folge von Zeichen. Das gilt dann auch für die TStringList. In der Entwicklung von Software ist es immer gut möglichst die Typen so zu benennen wie sie Dinge in der Realität auch sind. Der Name "string" ist dann meist allgemeiner als nötig. So wäre z.B. eine TElementIdList aussagekräftiger als eine TStringList. Man bekommt dann auch die Vorteile der ![]() Was ich auch schon oft sah ist dass alles Mögliche in einen String gepackt wurde, nur damit man eine TStringList verwenden konnte. Ich habe das früher auch gemacht, seit es auch in Delphi Generics gibt, sehe ich den Grund nicht mehr dazu. |
AW: Webinar FreeAndNil
Um eine Liste von Strings zu verwalten, ist eine TStringList doch die beste Option. Nur wenn man sie für andere Daten missbraucht, kann man evtl. von einer fehlerhaften Architektur sprechen.
|
AW: Webinar FreeAndNil
:oops: Ich finde das Thema toll, weil ich genau so ein Problem gerade habe und nicht weiß, wieso das so ist.
Zum Hintergrund: Ich habe einen "Out of memory"-Fehler bekommen. Also habe ich in den Bereich hineingesehen und bemerkt (irrtümlich aber wie es nun scheint), daß ich viel mit .create mache, aber am Ende gar kein .free setze. Also habe ich die Methoden ergänzt um jeweils try .. finally Es sind solche Dinge:
Delphi-Quellcode:
In dieser Procedure baue ich also eine JSON-Struktur aus, die ich dann an ein Gerät sende. Das funktioniert soweit prima (bis halt irgendwann Out of Memory kommt).
var json, p1, p2: TJSONObject;
jsonArr: TJSONArray; JsonToSend : TStream; Am Ende bin ich dann auf die Idee gekommen, ich sollte alles, was ich mit .create in der Procedure erstelle, auch wieder freigeben. Zwischendrin habe ich auch mal sowas geschrieben:
Delphi-Quellcode:
Und am Ende dann also (wobei ich in vielen Quelltextbeispielen am Ende keine Freigaben gesehen habe; mein Memoryleak scheint also woanders in der Verwendung mit JSON zu liegen) geschrieben:
if isCassette<>'TX' then
p1 := TJSONObject.Create else p1:=json; //gleiche Ebene
Delphi-Quellcode:
In der umgekehrten Reihenfolge habe ich jeweils .create gemacht (also erst json, dann die p1,p2 und dann jsonArr und zuletzt JsonToSend). Ich nehme an, daß die Reihenfolge der Freigabe auch wichtig ist.
finally
FreeAndNil(JsonToSend); FreeAndNil(jsonArr); FreeAndNil(p1); FreeAndNil(p2); FreeAndNil(json); end; Da habe ich dann aber eine "Ungültige Zeigeroperation" bekommen. Ich habe dann die Exception eingegrenzt zu FreeAndNil(json). json ist ein TJSONObject. Es scheint aber trotz seines naheliegenden Namens keine Ableitung von TObject zu sein, weil es dort knallt!? In der Hilfe zu "FreeAndNil(var Obj)" ist zu lesen: "Warnung: Obj muss eine Instanz einer von TObject abgeleiteten Klasse sein" - aha, und was wäre die Folge wenn nicht?? Und woher weiß ich welche Objekte, mit denen ich .create mache, von TObject abgeleitet sind?! Die Hilfe ist oft nicht wirklich hilfreich. Bin so froh, daß es dieses Forum hier gibt. :thumb: Habs dann so versucht:
Delphi-Quellcode:
Knallt trotzdem bei json.free
finally
JsonToSend.Free; jsonArr.Free; json.Free; p1.Free; p2.free; end; Kann ich denn überhaupt .Free machen, wenn die json bereits NIL wäre? Müsste ich dann vorsichtshalber "if assigned(json) then json.free" schreiben? Oder wäre "if json<>nil then json.free" besser? Bin verwirrt. :pale: Was mache ich falsch und warum? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:46 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