我只是想知道,为什么大多数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,声明一个常数与默认值是一个更好的方法。
@H_502_6@解决方法
历史原因,多数。 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,不推荐。使用初始化的常量技术是一个很好的解决方案,因为编译器可以生成正确的代码,以确保在分配期间正确完成现有的记录值。
@H_502_6@ @H_502_6@ 原文链接:https://www.f2er.com/delphi/103576.html