Delphi中New是否自动初始化含托管字段的记录?
Delphi含托管类型记录指针的内存分配疑问解答
首先看你定义的记录和指针类型:
type POverlappedContext = ^TOverlappedContext; TOverlappedContext = record HttpApiCookieStrings: TArray<AnsiString>; HttpApiLogFieldStrings: array[0..25] of string; one_field: Integer end; var LOverlappedContext: POverlappedContext;
针对你的两个疑问,解答如下:
1. New是否会自动将内存清零,使所有字段正确初始化为0/nil/空值?
New 会自动初始化记录里的托管类型字段,但不会清零非托管的普通数值类型:
- 对于
TArray<AnsiString>这类动态数组,会被初始化为空数组(内部指针为nil); - 对于
array[0..25] of string里的每个string元素,都会被初始化为空字符串(内部指针nil,引用计数0); - 但像
one_field这种Integer类型的非托管字段,New不会对它做初始化,它的值是内存里的随机垃圾值。
简单说:托管类型会被正确初始化,非托管数值类型不会自动清零。
2. 是否需要在New之后调用FillChar/ZeroMemory?会有什么问题?
绝对不要这么做。原因如下:
New已经为托管类型字段完成了合法的初始化(比如string会建立有效的空字符串结构,动态数组会设置合法的nil指针);- 调用
FillChar或ZeroMemory会直接把这些托管字段的内存覆盖为0,破坏它们的内部合法结构。比如原本的string字段是一个指向空字符串的有效指针,被清零后变成无效的空指针,后续当记录被释放时,Delphi的内存管理器会尝试处理这些被破坏的托管对象,大概率会引发访问违规,或者导致原本应该被正确释放的托管内存泄漏,最终出现未定义行为。
总结:不需要调用这类清零函数,调用反而会引发严重问题。
内容的提问来源于stack exchange,提问作者zeus
相关产品推荐
相关产品推荐

