procedure TForm1.Button1Click(Sender: TObject);
var
pBuffer: PAnsiChar;
begin
FreeMem(pBuffer);
ShowMessage('Test1');
end;
此代码是错误的,因为我们先使用FreeMem()
而没有使用GetMem()
。但我只是想知道,如果这种情况发生在一个大型项目中,为什么 Delphi 会挂起得这么厉害。
从 IDE 运行,我们没有收到任何错误FreeMem()
,但是在ShowMessage()
:
项目 Project1.exe 引发异常类 $C0000096,消息为“0x02df81f8 处的特权指令”。
运行可执行文件时,整个应用程序会挂起并显示白色消息。无法关闭它。如果您离开该窗口一段时间,则会以“级联”方式收到更多白色消息。
如果您替换ShowMessage()
为Application.MessageBox()
,则不会引发任何错误,但是当您尝试关闭应用程序时,您会收到错误“无效指针”,但奇怪的是有时会出现这种情况。
procedure TForm1.Button1Click(Sender: TObject);
var
pBuffer: PAnsiChar;
begin
FreeMem(pBuffer);
Application.MessageBox(PChar('Test'), PChar(Application.Title), MB_ICONINFORMATION OR MB_TASKMODAL);
end;
我想知道是否可以FreeMem()
安全地使用它。我尝试用这个 proc 来替换FreeMem()
这里找到的:使用单个函数在 Delphi 中释放内存和 nil但它没有帮助,在ShowMessage()
使用后使用时我得到了同样的错误FreeMemAndNil()
。
procedure TForm1.FreeMemAndNil(var P);
var
Tmp: Pointer;
begin
Tmp := Pointer(P);
Pointer(P) := nil;
FreeMem(Tmp);
end;
您正在使用未正确分配的内存来调用未定义的行为。
编译器不会自动将局部指针变量清零。您的
pBuffer
变量未初始化,因此它将包含其占用的内存块中已经存在的任何随机值。因此,您传递了一个无效指针FreeMem()
,因此会损坏随机内存。您的
ShowMessage()
调用恰好是这种损坏的不知情的受害者。您的MessageBox()
调用“有效”只是因为它使用了未损坏的不同内存。但这些都不是保证的行为。您有责任正确初始化指针。您可以安全地将
nil
指针传递给FreeMem()
,但不能安全地将非零指针传递给未分配GetMem()
或其他兼容函数的内存。FreeMemAndNil()
只是一种创可贴。它会nil
在释放指针指向的内存时释放指针,但如果指针一开始就无效,它就帮不了你,也不会释放指向同一内存的任何其他指针。你最终要负责正确管理你的指针。