gpt4 book ai didi

delphi - 为什么大多数 Delphi 示例使用 FillChar() 来初始化记录?

转载 作者:行者123 更新时间:2023-12-03 14:33:05 24 4
gpt4 key购买 nike

我只是想知道,为什么大多数 Delphi 示例都使用 FillChar() 来初始化记录。

type
TFoo = record
i: Integer;
s: string; // not safe in record, better use PChar instead
end;

const
EmptyFoo: TFoo = (i: 0; s: '');

procedure Test;
var
Foo: TFoo;
s2: string;
begin
Foo := EmptyFoo; // initialize a record

// Danger code starts
FillChar(Foo, SizeOf(Foo), #0);
s2 := Copy("Leak Test", 1, MaxInt); // The refcount of the string buffer = 1
Foo.s = s2; // The refcount of s2 = 2
FillChar(Foo, SizeOf(Foo), #0); // The refcount is expected to be 1, but it is still 2
end;
// After exiting the procedure, the string buffer still has 1 reference. This string buffer is regarded as a memory leak.

这里(http://stanleyxu2005.blogspot.com/2008/01/potential-memory-leak-by-initializing.html)是我关于这个主题的注释。 IMO,声明一个具有默认值的常量是一个更好的方法。

最佳答案

主要是历史原因。 FillChar() 可以追溯到 Turbo Pascal 时代并用于此类目的。这个名字确实有点用词不当,因为虽然它说的是 FillChar(),但它实际上是 FillByte()。原因是最后一个参数可以采用字符字节。因此 FillChar(Foo, SizeOf(Foo), #0) 和 FillChar(Foo, SizeOf(Foo), 0) 是等效的。另一个令人困惑的来源是,截至 Delphi 2009,FillChar 仍然只填充字节,即使 Char 相当于 WideChar。在查看 FillChar 最常见的用途时,为了确定大多数人是否使用 FillChar 来实际用字符数据填充内存,或者只是用它来用某个给定的字节值初始化内存,我们发现后一种情况主导了它的使用而不是前者。因此,我们决定保持 FillChar 以字节为中心。

确实,如果未在正确的上下文中使用,则使用 FillChar 清除包含使用“托管”类型之一(字符串、变体、接口(interface)、动态数组)声明的字段的记录可能是不安全的。然而,在您给出的示例中,对本地声明的记录变量调用 FillChar 实际上是安全的,只要这是您对该范围内的记录执行的第一件事即可。原因是编译器已生成代码来初始化记录中的字符串字段。这已经将字符串字段设置为 0 (nil)。调用 FillChar(Foo, SizeOf(Foo), 0) 只会用 0 个字节覆盖整个记录,包括已经为 0 的字符串字段。将值分配给记录变量后使用 FillChar字符串字段,不推荐。使用初始化常量技术是这个问题的一个很好的解决方案,因为编译器可以生成正确的代码以确保现有的记录值在赋值期间正确完成。

关于delphi - 为什么大多数 Delphi 示例使用 FillChar() 来初始化记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/783825/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com