最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Delphi JSON library Error on destroying root object - Stack Overflow

programmeradmin6浏览0评论

I am using delphi 10.2 with implicit JSON libraries like JSON, JSON.Readers, JSON.Types and having an error while trying to free the root json object.

Since my code is complicated.. to simulate same error i made a little event as;

procedure TForm1.Button1Click(Sender: TObject);
var
  aJsonObj,aJsonObj2,aJsonObj3 : TJsonObject;
  aJsonArr : TJsonArray;
begin
  aJsonObj := TJsonObject.Create;
  aJsonObj2 := TJsonObject.Create;
  aJsonObj3 := TJsonObject.Create;
  aJsonArr := TJsonArray.Create;
  aJsonObj2.AddPair('aa','aa');
  aJsonObj3.AddPair('bbb','bbb');
  aJsonArr.Add(aJsonObj2);
  aJsonArr.Add(aJsonObj3);
  aJsonObj.AddPair('arr',aJsonArr);
  aJsonObj.AddPair('a',aJsonObj2);
  aJsonObj.AddPair('b',aJsonObj3);
  ShowMessage(aJsonObj.ToJSON);
  FreeAndNil(aJsonObj);
end;

i know.. im using the same object inside the object twice.. and thats what i want to cover. must i create my own recursive "DestroyJSONObject" procedure or is there another more elegant way?

I am using delphi 10.2 with implicit JSON libraries like JSON, JSON.Readers, JSON.Types and having an error while trying to free the root json object.

Since my code is complicated.. to simulate same error i made a little event as;

procedure TForm1.Button1Click(Sender: TObject);
var
  aJsonObj,aJsonObj2,aJsonObj3 : TJsonObject;
  aJsonArr : TJsonArray;
begin
  aJsonObj := TJsonObject.Create;
  aJsonObj2 := TJsonObject.Create;
  aJsonObj3 := TJsonObject.Create;
  aJsonArr := TJsonArray.Create;
  aJsonObj2.AddPair('aa','aa');
  aJsonObj3.AddPair('bbb','bbb');
  aJsonArr.Add(aJsonObj2);
  aJsonArr.Add(aJsonObj3);
  aJsonObj.AddPair('arr',aJsonArr);
  aJsonObj.AddPair('a',aJsonObj2);
  aJsonObj.AddPair('b',aJsonObj3);
  ShowMessage(aJsonObj.ToJSON);
  FreeAndNil(aJsonObj);
end;

i know.. im using the same object inside the object twice.. and thats what i want to cover. must i create my own recursive "DestroyJSONObject" procedure or is there another more elegant way?

Share Improve this question asked Mar 10 at 15:33 Serkan EkşioğluSerkan Ekşioğlu 2615 silver badges16 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 3

All descendants of TJSONAncestor provide a property Owned allowing the container to free the instance. If you don't want that, set Owned to False for all instances you want to manage yourself.

Your root aJsonObj has references to aJsonObj2 and aJsonObj3, and a reference to aJsonArr which also has references to aJsonObj2 and aJsonObj3.

As such, when aJsonObj is freed, it will free aJsonArr, which will free aJsonObj2 and aJsonObj3, and then aJsonObj will try to free aJsonObj2 and aJsonObj3 again and crash.

You have two choices:

  • use a separate TJSONObject instance for every object in the JSON. Don't share references.

    procedure TForm1.Button1Click(Sender: TObject);
    var
      aJsonObj, aJsonObj2, aJsonObj2b, aJsonObj3, aJsonObj3b: TJsonObject;
      aJsonArr : TJsonArray;
    begin
      aJsonObj := TJsonObject.Create;
      aJsonObj2 := TJsonObject.Create;
      aJsonObj3 := TJsonObject.Create;
      aJsonArr := TJsonArray.Create;
      aJsonObj2.AddPair('aa','aa');
      aJsonObj3.AddPair('bbb','bbb');
      aJsonArr.Add(aJsonObj2);
      aJsonArr.Add(aJsonObj3);
      aJsonObj.AddPair('arr',aJsonArr);
      aJsonObj2b := aJsonObj2.Clone as TJsonObject; // <-- add this
      aJsonObj.AddPair('a',aJsonObj2b);
      aJsonObj3b := aJsonObj3.Clone as TJsonObject; // <-- add this
      aJsonObj.AddPair('b',aJsonObj3b);
      ShowMessage(aJsonObj.ToJSON);
      FreeAndNil(aJsonObj);
    end;
    
  • if you must share references, then set Owned=false on aJsonObj2 and aJsonObj3, and then free them explicitly yourself.

    procedure TForm1.Button1Click(Sender: TObject);
    var
      aJsonObj,aJsonObj2,aJsonObj3 : TJsonObject;
      aJsonArr : TJsonArray;
    begin
      aJsonObj := TJsonObject.Create;
      aJsonObj2 := TJsonObject.Create;
      aJsonObj2.Owned := False; // <-- add this
      aJsonObj3 := TJsonObject.Create;
      aJsonObj3.Owned := False; // <-- add this
      aJsonArr := TJsonArray.Create;
      aJsonObj2.AddPair('aa','aa');
      aJsonObj3.AddPair('bbb','bbb');
      aJsonArr.Add(aJsonObj2);
      aJsonArr.Add(aJsonObj3);
      aJsonObj.AddPair('arr',aJsonArr);
      aJsonObj.AddPair('a',aJsonObj2);
      aJsonObj.AddPair('b',aJsonObj3);
      ShowMessage(aJsonObj.ToJSON);
      FreeAndNil(aJsonObj);
      FreeAndNil(aJsonObj2); // <-- add this
      FreeAndNil(aJsonObj3); // <-- add this
    end;
    
发布评论

评论列表(0)

  1. 暂无评论