Delphi TJSONArray内存泄漏:无法释放JSON容器/对象

Delphi TJSONArray内存泄漏:无法释放JSON容器/对象,delphi,memory-leaks,delphi-xe6,Delphi,Memory Leaks,Delphi Xe6,下图列出了以下代码导致的内存泄漏: 方法: procedure TInformationSource.SetConfig; var vJSONConfigList : TStringList; vCurrentFileName : string; vDebugString : string; begin if iCJSONByteStream = nil then iCJSONByteStream := TBytesStream.Create;

下图列出了以下代码导致的内存泄漏:

方法:

    procedure TInformationSource.SetConfig;
var
  vJSONConfigList : TStringList;
  vCurrentFileName : string;
  vDebugString : string;

begin

    if iCJSONByteStream = nil then
      iCJSONByteStream := TBytesStream.Create;

    if vJSONConfigList = nil then
      vJSONConfigList := TStringList.Create;

    for vCurrentFileName in uCInformationSourceConfigFileNames do
    begin

      iCJSONBytes := TFile.ReadAllBytes(vCurrentFileName);
      iCJSONAsStr := TFile.ReadAllText(vCurrentFileName);

      fMain.jdInformationSource.JsonText := iCJSONAsStr;
      fMain.jtvInformationSource.LoadJson(false);

      if iCConfigsList = nil then
        iCConfigsList := TStringList.Create;
      if iCJSONData = nil then
        iCJSONData := TJSONArray.Create; // TJSONObject.Create();


      iCJSONConfigData := TJSONObject.ParseJSONValue(iCJSONBytes , 0) as TJSONObject;

      vDebugString := iCJSONConfigData.ToString;
      iCEndpoint             := GetActiveEndpoint;
      iCHeaderParams         := GetActiveHeaderParams;
      iCActiveAuthParams     := GetActiveAuthParams;
      iCActiveProtocolParams := GetActiveProtocolParams;
      iCActiveSourceName     := GetActiveSourceName;
end;end;
对象的析构函数:

    destructor TInformationSource.Destroy;
begin

  FreeandNil(iCHeaderParams);         // Okay
  FreeandNil(iCActiveProtocolParams); // Okay
  FreeandNil(iCJSONByteStream);       // Okay
  FreeandNil(iCConfigsList);          // Okay
  FreeandNil(uCInformationSourceConfigFileNames);  //Okay

  //FreeandNil(iCJSONConfigData);      // nil pointer access violation - Why?
  //FreeandNil(iCActiveAuthParams);    // nil pointer access violation - Why?
  //FreeandNil(iCJSONData);            // nil pointer access violation because TJSONArray Virtual base class?
  //FreeandNil(iCAuthPairs);           // nil pointer access violation because TJSONArray Virtual base class?

  inherited;
end;
声明:

//...
       private
   iCJSONData             : TJSONArray;
    iCAuthPairs            : TJSONArray;
    iCHeaderParams         : TJSONObject;
    iCActiveAuthParams     : TJSONArray;
    iCActiveProtocolParams : TJSONObject;
    iCActiveSourceName     : String;
    iCJSONAsStr : string;
    iCJSONBytes : TBytes;
    iCJSONByteStream : TBytesStream;
    iCConfigsList : TStringList;
    iCJSONConfigData : TJSONObject;
//...
现在,析构函数中最后5条FreeandNil语句都传递了访问冲突。对于TJSONArray实例,我目前的理解是,要么您无法释放和取消TJSONArray对象,因为您无法使用来构造它们。首先,创建编译器会抱怨您已使用虚拟方法从类实例化了对象,要么您只能使用TJSONValue.GetValue。然而,我不确定这是否是真的,如果是真的,我也不确定为什么会有这种差异。见下一段

TJONValue是密封类TJSONArray和TJSONObject的虚拟基类,因此是不可扩展类。我正在通过调用TJSONObject.ParseJSONValue和TJSONValue.GetValue创建后一个对象的实例,其中X是要返回的值TJSONArray、TJSONObject的类型

现在,我似乎在调用TObjectTJSONObject.ParseJSONValue…,TByteArray(返回有效值)创建的TJSONObject实例上获得FreeandNil的访问冲突,而在调用TJSONValue.GetValuekeystring创建的TJSONObject上没有获得访问冲突

我不明白这是为什么

TMoveArray泄漏是否与泄漏的TJSONArray对象有关联


另外一个问题是-如何释放与TBytes实例关联的内存,TBytes实例是泛型TArray的实例,其中类型约束是type Bytes?图像中的一些内存泄漏也与这些相关。或者这是自动完成的,因此不会导致下面的内存泄漏列表。

这是一个充满泄漏的代码。SetConfig有一个未被释放的本地TStringList,它甚至没有被使用。循环正在为多个文件调用TJSONObject.ParseJSONValue,但将结果分配给单个重用变量,而每次都不释放前一个对象。我怀疑您打算将iCJSONConfigData添加到iCJSONData,但忘记了这样做。如果是这种情况,则析构函数不应释放iCJSONConfigData,因为iCJSONData拥有它,只需释放iCJSONData本身,它将为您释放包含的对象。我已在FastMM上激活泄漏检测,并且在其当前状态下未报告泄漏。不要释放iCJSONConfigData,因为iCJSONData拥有它,仅仅释放iCJSONData本身,这确实是问题的一部分。事实上,我已经将iCJSONConfigData对象的成员分配给了第二个五个对象,因为它们与业务对象的属性相关联,这些业务对象只是在iCJSONConfig数据中公开了叶节点JSON对象,iCJSONConfig数据由一个大的JSON配置文件填充。因此,当我销毁第二组时,我正在释放已经释放的部分iCJSONConfig数据。感谢heaps Remy。在XE6和XE7中向析构函数添加异常处理程序的状态如何?因为异常处理程序阻止继承,这仍然是一个坏主意吗?无论如何都不应该允许析构函数引发异常。如果您正确地编写对象代码,析构函数应该始终能够清理处于已知状态的资源。在析构函数中没有什么是未知的。