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

标签 delphi initialization record

我只是想知道,为什么大多数 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/

相关文章:

android - 为什么 Android 不允许您在资源名称中使用大写字母?

arrays - `int *p` 和 `int (*p)[3]` 之间的区别?

delphi - Delphi 中的录音/保存

delphi - 将自定义 CodeInsight 管理器注册到 C++Builder,无需初始化/终止部分

multithreading - 多线程德尔福

initialization - 卡尔曼滤波器: Do I need to compute P in real time? 看来它的演化只取决于它的初始状态

mysql根据以前的记录增加值

delphi - 我的程序如何收集有关其自身的匿名使用数据?

mysql - 可以 select ... into outfile 而不是将其保存到文件中,而是将其保存在 blob 中

Mysql设置一条记录为删除或归档