Delphi 对象的字段中的动态数组会在对象被销毁时自动 deallocated/freed 吗?
Will dynamic arrays in fields of Delphi objects be automatically deallocated/freed when the object is destroyed?
如果我有一个 Delphi 对象包含一个带有动态数组的字段(包含例如字符串),如下所示:
TClassWithDynArrayField = class(TObject)
public
some_dyn_array : array of string;
end;
当对象被销毁时,这个数组(and/or它的内容)会自动deallocated/freed,还是我必须在对象的析构函数中以某种方式明确地完成它以避免内存泄漏或其他问题(字符串和动态数组的垃圾收集器崩溃,或其他与堆相关的代码等)?
如果答案是“是的,它会在对象被销毁后立即自动释放,也不会为 string/dynamic 数组垃圾收集留下任何不一致”,对于 multi 也是如此级动态数组字段?例如像这样:
TClassWithMultiLevelDynArrayField = class(TObject)
public
some_multi_level_dyn_array : array of array of string;
end;
如果我改为使用定义这些数组的“通用”方式(单级 and/or 多级)(据我所知,这在内部等同于动态数组的“非泛型”定义,是不是?),如下:
TClassWithGenericMultiLevelDynArrayField = class(TObject)
public
some_generic_multi_level_dyn_array : TArray<TArray<string>>;
end;
注意:对于所有这些示例,请假设其他代码会在对象被销毁之前任意填充数组的所有级别。
我问这个的原因是,在对象(和动态分配的记录)中使用动态数组时,我似乎经常遇到奇怪的访问冲突,而且 [=16= 中有一些半相关的讨论],看似区分动态数组的自动重新分配,例如字符串(即在基于 Dispose 的释放的情况下,但我认为它也可以应用于对象字段?),如下所示:
Finalize should be used only in Delphi code where a dynamically allocated variable is deallocated by other means than the Dispose procedure. Dynamic arrays can never be deallocated using the Dispose procedure, but can be freed by passing them to Finalize.
For global variables, local variables, objects, and dynamic variables deallocated using Dispose, the compiler generates code that finalizes all long strings, variants, and interfaces contained by the variable when the instance is destroyed.
If a dynamic variable meets the following two conditions, a call to Finalize is required to finalize the variable before it can be deallocated.
The variable is deallocated by other means than the Dispose standard procedure (for example, using FreeMem).
The variable contains long strings, variants, or interfaces, not all of which are empty or Unassigned.
Finalize simply sets all long strings to empty and all variants and interfaces to Unassigned, thus properly releasing any memory that was referenced by the long strings and variants.
请注意,在提到字符串的那些情况下从未提到过动态数组,并且在第一句中提到动态数组是某种“手动”特例?
所以,再说一次,当对象被销毁时,Delphi 对象字段中的动态数组会自动 deallocated/freed,无论它们有多填充,例如字符串,无论它们是否是任意多的“深度”(即动态数组内部的动态数组),如我上面的示例?
是的,动态数组字段的处理方式与长字符串和其他编译器管理的变量一样,无论现在有多深。
它们的引用计数将在对象的析构函数中递减,如果计数为零,数组将被释放。
如果我有一个 Delphi 对象包含一个带有动态数组的字段(包含例如字符串),如下所示:
TClassWithDynArrayField = class(TObject)
public
some_dyn_array : array of string;
end;
当对象被销毁时,这个数组(and/or它的内容)会自动deallocated/freed,还是我必须在对象的析构函数中以某种方式明确地完成它以避免内存泄漏或其他问题(字符串和动态数组的垃圾收集器崩溃,或其他与堆相关的代码等)?
如果答案是“是的,它会在对象被销毁后立即自动释放,也不会为 string/dynamic 数组垃圾收集留下任何不一致”,对于 multi 也是如此级动态数组字段?例如像这样:
TClassWithMultiLevelDynArrayField = class(TObject)
public
some_multi_level_dyn_array : array of array of string;
end;
如果我改为使用定义这些数组的“通用”方式(单级 and/or 多级)(据我所知,这在内部等同于动态数组的“非泛型”定义,是不是?),如下:
TClassWithGenericMultiLevelDynArrayField = class(TObject)
public
some_generic_multi_level_dyn_array : TArray<TArray<string>>;
end;
注意:对于所有这些示例,请假设其他代码会在对象被销毁之前任意填充数组的所有级别。
我问这个的原因是,在对象(和动态分配的记录)中使用动态数组时,我似乎经常遇到奇怪的访问冲突,而且 [=16= 中有一些半相关的讨论],看似区分动态数组的自动重新分配,例如字符串(即在基于 Dispose 的释放的情况下,但我认为它也可以应用于对象字段?),如下所示:
Finalize should be used only in Delphi code where a dynamically allocated variable is deallocated by other means than the Dispose procedure. Dynamic arrays can never be deallocated using the Dispose procedure, but can be freed by passing them to Finalize.
For global variables, local variables, objects, and dynamic variables deallocated using Dispose, the compiler generates code that finalizes all long strings, variants, and interfaces contained by the variable when the instance is destroyed.
If a dynamic variable meets the following two conditions, a call to Finalize is required to finalize the variable before it can be deallocated.
The variable is deallocated by other means than the Dispose standard procedure (for example, using FreeMem).
The variable contains long strings, variants, or interfaces, not all of which are empty or Unassigned.
Finalize simply sets all long strings to empty and all variants and interfaces to Unassigned, thus properly releasing any memory that was referenced by the long strings and variants.
请注意,在提到字符串的那些情况下从未提到过动态数组,并且在第一句中提到动态数组是某种“手动”特例?
所以,再说一次,当对象被销毁时,Delphi 对象字段中的动态数组会自动 deallocated/freed,无论它们有多填充,例如字符串,无论它们是否是任意多的“深度”(即动态数组内部的动态数组),如我上面的示例?
是的,动态数组字段的处理方式与长字符串和其他编译器管理的变量一样,无论现在有多深。
它们的引用计数将在对象的析构函数中递减,如果计数为零,数组将被释放。