当对象被销毁时,Delphi对象字段中的动态数组是否会被自动释放/释放?

时间:2015-03-02 01:15:37

标签: delphi destructor dynamic-memory-allocation dynamic-arrays

如果我有一个包含带动态数组的字段的Delphi对象(包含例如字符串),如下所示:

   TClassWithDynArrayField = class(TObject)
   public
      some_dyn_array : array of string;
   end;

当对象被销毁时,这个数组(和/或它的内容)会被自动释放/释放,还是我必须在对象的析构函数中以某种方式显式地完成它,以避免内存泄漏或其他讨厌(垃圾收集器中的字符串和动态数组崩溃,或其他堆相关的代码等)?

如果答案是"是的,一旦对象被销毁,它就会自动解除定位,同时也不会对字符串/动态数组垃圾收集产生任何不一致的情况,对于#34;同样也是如此。多级动态数组字段?例如:

   TClassWithMultiLevelDynArrayField = class(TObject)
   public
      some_multi_level_dyn_array : array of array of string;
   end;

如果我改为使用" generic"答案会有什么不同吗?定义这些数组(单级和/或多级)的方式(来自我所听到的内部等同于"非泛型"动态数组的定义,或isn&#39是吗?),如下:

   TClassWithGenericMultiLevelDynArrayField = class(TObject)
   public
      some_generic_multi_level_dyn_array : TArray<TArray<string>>;
   end;

注意:对于所有这些示例,请假设其他代码将在对象被销毁之前随意填充所有级别的数组。

我之所以这样说是因为在对象(和动态分配的记录)中使用动态数组时,我常常会出现奇怪的访问冲突,并且在{{3}中有一些半相关的谈话,似乎区分动态数组的自动释放,例如字符串(即在基于Dispose的解除分配的情况下,但我认为它也可以应用于对象字段?),如下所示:

  

Finalize只能在Delphi代码中使用,其中动态分配的变量通过除Dispose过程之外的其他方式释放。 动态数组永远不能使用Dispose过程释放,但可以通过将它们传递给Finalize 来释放。

     

对于全局变量,使用Dispose释放的局部变量,对象和动态变量,编译器生成代码,以在销毁实例时最终确定变量包含的所有长字符串,变量和接口

     

如果动态变量满足以下两个条件,则需要调用Finalize来最终确定变量,然后才能解除分配。

     
      
  • 通过Dispose标准程序以外的其他方式释放变量(例如,使用FreeMem)。

  •   
  • 该变量包含长字符串,变体或接口,并非全部为空或未分配。

  •   
     

Finalize只需将所有长字符串设置为空,将所有变量和接口设置为Unassigned,从而正确释放长字符串和变体引用的所有内存。

请注意,在提到字符串的情况下,从未提及动态数组,并且动态数组也被称为某种&#34;手册&#34;第一句中的特例?

因此,当对象被销毁时,Delphi对象字段中的动态数组将被自动解除分配/释放,无论它们如何填充,例如字符串,无论它们是否是任意多的&#34;水平深度&#34; (即动态数组中的动态数组),如上面的示例所示?

1 个答案:

答案 0 :(得分:5)

是的,动态数组字段的处理方式就像长字符串和其他编译器管理的变量一样,无论现在多层次都是如此。

它们的引用计数将在对象的析构函数中递减,如果计数为零,则将丢弃该数组。