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

前端之家收集整理的这篇文章主要介绍了为什么大多数Delphi示例使用FillChar()来初始化记录?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我只是想知道,为什么大多数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,#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清除包含使用“托管”类型(字符串,变量,接口,动态数组)之一声明的字段的记录可能是不安全的,如果不在正确的上下文中使用。但是,在您给出的示例中,只要在该范围内记录的第一件事就是在本地声明的记录变量上调用FillChar就是安全的。原因是编译器已经生成代码来初始化记录中的字符串字段。这将已经将字符串字段设置为0(nil)。调用FillChar(Foo,SizeOf(Foo),0)将仅覆盖0个字节的整个记录​​,包括已经为0的字符串字段。在将值分配给字符串字段后,在记录变量上使用FillChar,不推荐。使用初始化的常量技术是一个很好的解决方案,因为编译器可以生成正确的代码,以确保在分配期间正确完成现有的记录值。

原文链接:https://www.f2er.com/delphi/103576.html

猜你在找的Delphi相关文章