delphi无效的指针操作

时间:2014-01-02 09:03:40

标签: 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;

运行此代码段后,FreeMem(ptr)将引发错误:'指针操作无效'。如果我删除句子:

     ptr:=Pchar('OneNationUnderGod');

然后不会发生错误。现在我有两个问题,

1.为什么会发生这种情况? 2.如果我必须使用Pchar句子,我应该如何释放先前分配的内存?

非常感谢您的帮助!

3 个答案:

答案 0 :(得分:5)

问题是您正在修改变量ptr中保存的地址。

您调用AllocMem来分配缓冲区,您可以使用ptr来引用该缓冲区。那很好。但是你必须永远不要改变ptr的值,即缓冲区的地址。而你确实改变了它。

您写道:

ptr:=AllocMem(40);
ptr:=Pchar('OneNationUnderGod');

第二行是问题所在。你已经修改了ptr,现在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为nil的测试是不必要的。 AllocMem永远不会返回nil。 AllocMem失败导致异常被引发。


说了这么多,以这种方式操作字符串缓冲区并不常见。使用Delphi字符串是正常的。如果您需要一个PChar,例如与interop一起使用,请使用PChar(str)创建一个,其中str是string类型。

你说你必须使用动态分配的PChar缓冲区。也许就是这样,但我非常怀疑它。

答案 1 :(得分:1)

崩溃是因为您释放了未动态分配的静态内存。根本不需要释放文字所使用的内存。只有动态分配的空闲内存。

答案 2 :(得分:1)

我会尝试让你做得更明确。你似乎把变量的名称误认为是错误的。然而实际上 - 考虑到价值 - 你所做的是

 ptrA:=AllocMem(40);
 ptrB:=Pchar('OneNationUnderGod');
 if ptrB<>nil then 
     FreeMem(ptrB);

每个新赋值都会更改覆盖前一个赋值的值,从而释放另一个已分配的指针。

您可以阅读StrNew,StrDispose,StrCopy,StrLCopy和示例代码等文档的文档,以查看使用PChar字符串的一些模式。