AGB  ·  Datenschutz  ·  Impressum  







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

Webinar FreeAndNil

Ein Thema von Rollo62 · begonnen am 24. Jun 2022 · letzter Beitrag vom 4. Jul 2022
Antwort Antwort
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.666 Beiträge
 
Delphi 12 Athens
 
#1

AW: Webinar FreeAndNil

  Alt 30. Jun 2022, 10:45
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.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
SearchBot

Registriert seit: 27. Jun 2004
Ort: N-W vom Bodensee
328 Beiträge
 
Delphi 12 Athens
 
#2

AW: Webinar FreeAndNil

  Alt 30. Jun 2022, 13:58
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:
var json, p1, p2: TJSONObject;
    jsonArr: TJSONArray;
    JsonToSend : TStream;
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).
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:
  if isCassette<>'TXthen
   p1 := TJSONObject.Create
  else
   p1:=json; //gleiche Ebene
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:
Delphi-Quellcode:
 finally
  FreeAndNil(JsonToSend);
  FreeAndNil(jsonArr);
  FreeAndNil(p1);
  FreeAndNil(p2);
  FreeAndNil(json);
 end;
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.

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.

Habs dann so versucht:
Delphi-Quellcode:
 finally
  JsonToSend.Free;
  jsonArr.Free;
  json.Free;
  p1.Free;
  p2.free;
 end;
Knallt trotzdem bei json.free

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.
Was mache ich falsch und warum?
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.666 Beiträge
 
Delphi 12 Athens
 
#3

AW: Webinar FreeAndNil

  Alt 30. Jun 2022, 14:51
Beim Aufruf von Free bzw. FreeAndNil musst Du nicht vorher auf Assigned oder nil prüfen, das tun die Methoden bereits intern, im Gegensatz zu Destroy. Zu Deinem Problem: falls das JSONObject Teil eines anderen JSON-Objekts ist, kümmert sich dies bereits um die Freigabe, mit der Zuweisung holst Du Dir dann lediglich einen weitere Referenz, aber keine neue Instanz. Rufst Du also hier Free auf einer bereits vom "Eltern-JSON" freigegebenen Referenz auf, knallt es natürlich, da hilft auch kein FreeAndNil.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.814 Beiträge
 
Delphi 12 Athens
 
#4

AW: Webinar FreeAndNil

  Alt 1. Jul 2022, 09:25
Die ganze Diskussion zeigt doch nur eines: Die einzige Strafe, die die Verwendung von FreeAndNil mit sich bringt ist ein missbilligender Blick des Kollegiums. Es gibt keine Performance Strafe, es gibt keine Fehler. Es ist alles gut. Und damit kann ich wunderbar leben.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
10.043 Beiträge
 
Delphi 12 Athens
 
#5

AW: Webinar FreeAndNil

  Alt 1. Jul 2022, 12:18
Es gibt keine Performance Strafe
Ganz kostenlos ist der Aufruf nicht, aber solange man das nicht in einer Schleife sehr oft aufruft, spielt das keine Rolle. Das try..finally Handling dürfte da ohnehin teurer sein.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Webinar FreeAndNil

  Alt 1. Jul 2022, 12:29
FreeAndNil hat doch kein Try-Finally drin?

Drum macht es ja eigentlich NilAndFree, im sich das Try-Finally zu sparen.



Einzig, wo es im FreeAndNil Probleme geben könnte, wenn im Destructor oder etwas darin Aufgerufenem oder anderem Freigegeben irgendwo auf diese (globale) Variable zugegriffen würde.
z.B. im OnDestroy der Form auf die Form-Variable, anstatt auf Self.

Hier ist die Variable ja schon vorher NIL und es würde dann knallen.


Genau aus dem Grund setzt Application.FormCreate schon vor dem Constructor/OnCreate die Variable, falls jemand beim Laden auf diese Variable zugreift.
und automatisch werden die FormVariablen nicht genilt, weswegen es dann beim Freigeben auch nicht mehr knallt.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.730 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

AW: Webinar FreeAndNil

  Alt 1. Jul 2022, 13:05
FreeAndNil hat doch kein Try-Finally drin?

Drum macht es ja eigentlich NilAndFree, im sich das Try-Finally zu sparen.
Inwiefern spart FreeAndNil ein Try..Finally? Ich rufe FreeAndNil nämlich immer im Finally-Block auf. Also so:
Delphi-Quellcode:
  bla := nil;
  blub := TSomeObject.Create;
  try
    bla := TSomeOther.Create;

  finally
     FreeAndNil(bla);
     FreeAndNIl(blub);
  end;
Könnte ich da das Try..Finally irgendwie einsparen?
Thomas Mueller
  Mit Zitat antworten Zitat
Antwort Antwort


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