问题在于您修改了变量ptr中保存的地址。
您调用AllocMem来分配一个缓冲区,并使用ptr引用它,这一点很好。但是您绝不能改变ptr的值,即缓冲区的地址。而您确实改变了它。
您写道:
ptr:=AllocMem(40);
ptr:=Pchar('OneNationUnderGod');
第二行是问题所在。你已经修改了ptr,现在它指向了其他的东西(恰好是保存在只读内存中的字符串文字)。你已经失去了跟踪调用AllocMem分配的缓冲区的能力。你请求AllocMem为你分配了一块新的内存块,然后立即丢弃了那个内存块。
你可能想要做的是复制字符串。也许像这样:
ptr := AllocMem(40);
StrCopy(ptr, 'OneNationUnderGod');
现在我们可以放心调用 FreeMem,因为 ptr 仍然包含了调用 AllocMem 提供的地址。
ptr := AllocMem(40);
try
StrCpy(ptr, 'OneNationUnderGod');
// do stuff with ptr
finally
FreeMem(ptr);
end;
显然在实际代码中,您会找到更好和更强大的方法来指定缓冲区长度,而不是硬编码数值。
在您的代码中,假设上述修复已应用,则检查ptr是否为空无需。AllocMem从不返回nil。AllocMem失败会导致异常被引发。
尽管如此,通常不会以这种方式操作字符串缓冲区。使用Delphi字符串是正常的。例如,如果您需要PChar与Interop一起使用,则可以使用PChar(str)创建一个str类型的PChar。
您说您必须使用动态分配的PChar缓冲区。也许确实如此,但我非常怀疑。