GetMem和AllocMem有什么区别?

ala*_*ncc 0 memory delphi allocation

在Delphi中,我看到了几个可以用来分配内存的类似函数,例如GetMem和AllocMem。它们之间有什么区别?

我阅读了文档,发现分配后GetMem不会初始化内存,而AllocMem会初始化。

那我在调用GetMem之后是否需要初始化内存?医生说是。但是我在某些Delphi源代码中看到它们不调用Initialize。

以及在使用完内存后是否需要最后确定内存?我在一些Delphi源代码中看到了,但是确实没有。

谢谢

MBo*_*MBo 6

逻辑看起来很简单-如果您需要零初始化的缓冲区,则可以使用AllocMem

如果您在任何情况下都用自己的数据填充缓冲区,并且从不使用默认内容,则可以使用GetMem


And*_*and 5

区别在于AllocMem用零填充新分配的缓冲区,而GetMem不会填充零。如果您的代码要求新分配的缓冲区最初为全零,则可以使用AllocMem代替在缓冲区中手动写入零;如果您不关心缓冲区中的初始字节,则可以(可能)更便宜GetMem

例如,

var
  p: PByte;
begin
  GetMem(p, 1024);
  try
    p^ := 20;
    (p + 1)^ := 30;
    (p + 2)^ := p^ + (p + 1)^;
    ShowMessage((p + 2)^.ToString);
  finally
    FreeMem(p);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

有效并且将始终显示50,但是

GetMem(p, 1024);
try
  p^ := 20;
  (p + 2)^ := p^ + (p + 1)^;
  ShowMessage((p + 2)^.ToString);
finally
  FreeMem(p);
end;
Run Code Online (Sandbox Code Playgroud)

可以显示任何内容-这完全取决于p + 1执行代码时的字节大小(机会)。

如果您首先用零填充缓冲区,如

GetMem(p, 1024);
try
  FillChar(p^, 1024, 0);
  p^ := 20;
  (p + 2)^ := p^ + (p + 1)^;
  ShowMessage((p + 2)^.ToString);
finally
  FreeMem(p);
end;
Run Code Online (Sandbox Code Playgroud)

您一定会看到的20,因为p + 1会坚持下去的0

或者,您可以

p := AllocMem(1024);
try
  p^ := 20;
  (p + 2)^ := p^ + (p + 1)^;
  ShowMessage((p + 2)^.ToString);
finally
  FreeMem(p);
end;
Run Code Online (Sandbox Code Playgroud)

因为文档保证AllocMem将新分配的缓冲区中的每个字节都设置为0

但是,当然,在堆上手动分配内存是为了(“高级”)低级内容。大多数情况下,您不这样做。如果这样做,则应注意内部数据格式之类的内容