AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Verständnisfrage: TJSONObject create/free/destroy?
Thema durchsuchen
Ansicht
Themen-Optionen

Verständnisfrage: TJSONObject create/free/destroy?

Ein Thema von SearchBot · begonnen am 26. Jul 2022 · letzter Beitrag vom 29. Jul 2022
Antwort Antwort
Benutzerbild von himitsu
himitsu
Online

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

AW: Verständnisfrage: TJSONObject create/free/destroy?

  Alt 26. Jul 2022, 12:52
Zitat:
Delphi-Quellcode:
   jsonArr:= TJSONArray.Create;
   jsonArr.Add(p1);
   jsonArr.Add(p2);

   json.AddPair('path', jsonArr);
  finally
   jsonArr.Free; <<<<
  end;
 finally
   //jetzt brauche ich diese Objekte nicht mehr also..
   p1.Free; // hier knallt es schon "Ungültige Zeigeroperation", ebenfalls mit .Destroy
   p2.Free;
 end;
Beim Add übernimmt das JSONArray die Kontrolle, also Dieses gibt beim ersten Free auch P1 und P2 mit frei.

Zitat:
Sollte ich besser destroy anstelle von free verwenden?
Nein.

Destroy ruft man im Allgemeinen niemals direkt auf.

Und wenn schon Free knallt, dann kann Destroy nur noch mehr knallen, weil das if Assigned(Self) im Free fehlt
und es dann nicht nur bei "ungültigen" Zeigern knallt, sondern auch noch bei nil.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (26. Jul 2022 um 13:07 Uhr) Grund: Schlechtschreibung
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#2

AW: Verständnisfrage: TJSONObject create/free/destroy?

  Alt 26. Jul 2022, 13:05
Beim Add übernimmt das JSONArray die Kontrolle, also Dieses gibt beim ersten Free auch P1 und P2 auf.
Das ist ähnlich wie bei TObjectList<T> oder TStringList mit OwnsObject = True. Auch in diesen beiden Fällen übernimmt die Klasse das Wegräumen der Objekte.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
SearchBot

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

AW: Verständnisfrage: TJSONObject create/free/destroy?

  Alt 26. Jul 2022, 13:29
Dankeschön

Aber warum schreibt dann die blöde Hilfe so widersprüchliches Zeugs??
Bei TJSONObject.create heißt es, mit .Destroy sei es aufzuräumen. Zudem ist .Free im Hilfe-Index garnicht aufgelistet.
Bei TJSONObject.AddPair hat ein Beispiel, das das JSON-Objekt mit .Free aufräumt.


Wäre ergänzend FreeAndNil sinnvoll?

Und wie kann ich das ahnen, daß das TJSONArray beim Free auch meine Objekte p1 und p2 mit in den Tod reißt?
Was kann ich tun, wenn ich die jetzt in einer Schleife habe und weiterverwenden möchte?
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.643 Beiträge
 
Delphi 12 Athens
 
#4

AW: Verständnisfrage: TJSONObject create/free/destroy?

  Alt 26. Jul 2022, 13:48
Das ist in der Doku aber ganz gut beschrieben: Framework der JSON-Objekte
Zitat:
Lebenszyklus

In JSON ist das übergeordnete Objekt Eigentümer aller Werte, die es enthält, außer deren Eigenschaft Owned ist auf False gesetzt. In diesem Fall werden bei der Freigabe eines JSON-Objekts alle Member übersprungen, deren Flag auf False gesetzt ist. Dadurch wird das Zusammenfügen verschiedener Objekte zu größeren Objekten unter Beibehaltung der Eigentümerschaft möglich. Per Vorgabe ist die Eigenschaft True, das bedeutet, dass alle enthaltenen Instanzen Eigentum des übergeordneten Objekts sind.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
BerndS

Registriert seit: 8. Mär 2006
Ort: Jüterbog
493 Beiträge
 
Delphi 12 Athens
 
#5

AW: Verständnisfrage: TJSONObject create/free/destroy?

  Alt 26. Jul 2022, 13:51
TJsonObject hat das Property Owned (TJSONAncestor).
Wenn du also P1.Owned := False setzt, sollte nichts freigegeben werden.
  Mit Zitat antworten Zitat
SearchBot

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

AW: Verständnisfrage: TJSONObject create/free/destroy?

  Alt 26. Jul 2022, 14:23
Aah, deshalb muss ich auch diese inline generierten Dinge nicht extra freigeben (zb das TJSONBool-Objekt in json.AddPair(prop, TJSONBool.Create(cv='true')); ). Das ist praktisch.

Und wenn ich also Owned=false setze, gebe ich es (wie für mich normal und nachvollziehbar) am Ende erst frei.
[getestet] Schön, es knallt nicht mehr.

Als Folge von Owned=false löst jetzt aber die Wertübergabe requestString:=json.ToString eine Zugriffsverletzung aus. Wieso?
Zerstört die Freigabe von P1 und P2 jetzt das plötzlich übergeordnete Objekt json (das ich auch Owned=false gesetzt habe)?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Verständnisfrage: TJSONObject create/free/destroy?

  Alt 26. Jul 2022, 14:45
Du kannst natürlich auch mit DebugDCUs kompilieren und dann einen Haltepunkt in TJSONObject.Destroy setzen und verfolgen wo/wann deine Objekte verschwinden und deine Variablen somit ungültig sind.

Teilweise könnte man auch mit [weak] arbeiten und seine Variable automatisch auf NIL setzen lassen, was aber nur bei aktivem ARC funktioniert (also leider nicht in Win32/Win64).
Delphi-Quellcode:
var
  [weak] J: TJSONObject;

oder z.B. sich anders ins Destroy reinhängen.
Delphi-Quellcode:
uses System.JSON, System.RTTI;

procedure TForm21.FormCreate(Sender: TObject);
var
  J: TJSONObject;
  VMI: TVirtualMethodInterceptor;
begin
  J := TJSONObject.Create;

  VMI := TVirtualMethodInterceptor.Create({TJSONObject} J.ClassType);
  VMI.Proxify(J);
  VMI.OnBefore := procedure(Instance: TObject; Method: TRttiMethod; const Args: TArray<TValue>; out DoInvoke: Boolean; out Result: TValue)
    begin
      if Method.Name = 'BeforeDestructionthen // eigentlich hötte ich "Destroy" genommen, aber will nicht ... erst BeforeDestruction und dann nur noch FreeInstance (aber eigentlich hätte es gehen müssen)
        Beep; << hier drauf einen Debugger-Haltepunkt
        // oder ShowMessage(Instance.ClassName);
        // oder ShowMessage(Instance.ClassName + ' ' + (Instance as TJSONAncestor).ToString); // Achtung, .ToString landet natürlich ebenfalls in VMI.OnBefore

      //DoInvoke := True; ist zwar OUT, aber eigentlich ist es VAR und bereits mit True initialisiert, also somit nicht unbedingt nötig
    end;

  //...

  J.Free; // selber oder z.B. irgendwo via Owned innerhalb eines anderen Objekts
end;
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (26. Jul 2022 um 14:49 Uhr)
  Mit Zitat antworten Zitat
SearchBot

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

AW: Verständnisfrage: TJSONObject create/free/destroy?

  Alt 26. Jul 2022, 15:01
Als Folge von Owned=false löst jetzt aber die Wertübergabe requestString:=json.ToString eine Zugriffsverletzung aus. Wieso?
Hab das TJSONArray nicht auf owned gesetzt.

@Himitsu: so tief will ich garnicht reingehen, aber trotzdem danke für diesen Tiefenblick.

Was wird eigentlich alles freigegeben, wenn die procedure zu Ende ist, in der ich die TJSON-Objekte erzeuge?
Wie kann ich messen, ob ich innerhalb einer procedure ein Speicherleck habe (ich habe bisher nur den Taskmanager beobachtet, wie sich der Speicher meiner App verändert)?

Edit:
Ich habe ein seltsamens Phänomen mit dem Inhalt von meiner json-Variable. Ich beobachte sie durch die Auswertung von json.toString.

Delphi-Quellcode:
    try
      jsonArr:= TJSONArray.Create;
      jsonArr.owned:=false;
      jsonArr.Add(p1);
      jsonArr.Add(p2);

      json.AddPair('path', jsonArr);
Bis hier steht in meinem json.toString:
'{"is_left_test_point":true,"installation_info":"" ,"path":[{"is_agc_on":false,"att_post":0,"eol":-7},{"is_agc_on":false,"att_post":0,"eol":1}]}'

Dann wird das ausgeführt:
Delphi-Quellcode:
    finally
     jsonArr.Free;
     jsonArr:=nil;
    end;
In dem Moment, wo jsonArr.Free gesetzt wird, ändert sich die json.toString zu:
'{"is_left_test_point":true,"installation_info":"" ,"path":{"is_left_test_point":true,"installation_i nfo":"",}'

Wie kann das denn sein?!?

Geändert von SearchBot (26. Jul 2022 um 15:13 Uhr) Grund: Neue Erkenntnisse...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Verständnisfrage: TJSONObject create/free/destroy?

  Alt 26. Jul 2022, 15:12
Delphi-Referenz durchsuchenReportMemoryLeaksOnShutdown := True;

Siehe Bei Google suchenFastMM Debug-Optionen

Oder eben sich ins Freigeben hängen ... dann siehst du was freigegeben wird (und was nicht)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Verständnisfrage: TJSONObject create/free/destroy?

  Alt 26. Jul 2022, 15:23
Wie kann ich messen, ob ich innerhalb einer procedure ein Speicherleck habe (ich habe bisher nur den Taskmanager beobachtet, wie sich der Speicher meiner App verändert)?
Dafür liebe ich den Process Hacker bereites seit vielen vielen Jahren, da sehe ich detailiert Speichernutzung, Handles etc... Find ich ist ein Klasse Tool um sowas mal rasch zu checken.
Gruß vom KodeZwerg
  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 08:06 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