wor*_*ace 1 delphi pointers memory-management runtime-error
这里我在delphi 7中运行了几行delphi代码:
var
ptr:Pointer ;
begin
ptr:=AllocMem(40);
ptr:=Pchar('OneNationUnderGod');
if ptr<>nil then
FreeMem(ptr);
end;
Run Code Online (Sandbox Code Playgroud)
运行此代码片段时,FreeMem(ptr)将引发错误:'无效指针操作'.如果我删除这句话:
ptr:=Pchar('OneNationUnderGod');
Run Code Online (Sandbox Code Playgroud)
那么就不会发生错误.现在我有两个问题,
为什么会这样?2.如果我必须使用Pchar句子,我应该如何释放先前分配的内存?
非常感谢您的帮助!
问题是您正在修改变量ptr中保存的地址.
您调用AllocMem来分配缓冲区,您可以使用ptr来引用该缓冲区.那很好.但是你必须永远不要改变ptr的值,即缓冲区的地址.你确实改变了它.
你写了:
ptr:=AllocMem(40);
ptr:=Pchar('OneNationUnderGod');
Run Code Online (Sandbox Code Playgroud)
第二行是问题所在.你已经修改了ptr,现在ptr引用了其他东西(在只读内存中保存的字符串文字).您现在已经忘记了通过调用AllocMem分配的缓冲区.您向AllocMem询问了新的内存块,然后立即丢弃了该内存块.
你想要做的就是复制字符串.也许是这样的:
ptr := AllocMem(40);
StrCopy(ptr, 'OneNationUnderGod');
Run Code Online (Sandbox Code Playgroud)
现在我们可以调用FreeMem,因为ptr仍然包含对AllocMem的调用所提供的地址.
ptr := AllocMem(40);
try
StrCpy(ptr, 'OneNationUnderGod');
// do stuff with ptr
finally
FreeMem(ptr);
end;
Run Code Online (Sandbox Code Playgroud)
显然,在实际代码中,您会发现一种更好,更健壮的方法来指定缓冲区长度而不是硬编码值.
在您的代码中,假设应用了上述修复,ptr为nil的测试是不必要的.AllocMem永远不会返回nil.AllocMem失败导致异常被引发.
说了这么多,以这种方式操作字符串缓冲区并不常见.使用Delphi字符串是正常的.如果您需要一个PChar,例如与interop一起使用,请使用PChar(str)创建一个,其中str是string类型.
你说你必须使用动态分配的PChar缓冲区.也许就是这样,但我非常怀疑它.