在下面的代码中,我遇到了意外的访问冲突错误:
program Project65;
{$APPTYPE CONSOLE}
{$R *.res}
uses
SysUtils;
type
ITest = interface
end;
TTest = class(TInterfacedObject, ITest)
end;
var
p: ^ITest;
begin
GetMem(p, SizeOf(ITest));
p^ := TTest.Create; // AV here
try
finally
p^ := nil;
FreeMem(p);
end;
end.
我知道接口应该有不同的使用方式。然而,我正在处理一个使用这种方法的旧代码库。我很惊讶地发现,仅仅保留 SizeOf(ITest) 的内存空间并不能满足放置 ITest 的需求。
有趣的是,如果我将第一行修改为
GetMem(p, 21);
当AV(访问冲突)发生时,程序会崩溃。在这里,我们需要预留比20字节更多的空间才能避免发生AV(20字节或更少的空间将导致失败)。为什么要预留21个字节而不是ITest的大小(4个字节)?请注意,我使用Delphi XE2 Update 4 + HotFix。