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 Typsicherheit. 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 05:25 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