GetMem和AllocMem有什么区别?

时间:2019-05-21 07:36:44

标签: delphi memory allocation

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

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

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

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

谢谢

3 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:4)

区别在于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; ,但是

50

是否可以显示任何内容-取决于执行代码时(机会)GetMem(p, 1024); try p^ := 20; (p + 2)^ := p^ + (p + 1)^; ShowMessage((p + 2)^.ToString); finally FreeMem(p); end; 上的字节。

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

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; ,因为20将持有p + 1

您也可以选择

0

因为文档保证p := AllocMem(1024); try p^ := 20; (p + 2)^ := p^ + (p + 1)^; ShowMessage((p + 2)^.ToString); finally FreeMem(p); end; 将新分配的缓冲区中的每个字节都设置为AllocMem

但是,当然,在堆上手动分配内存是为了(高级)低级的东西。大多数情况下,您不这样做。如果这样做,您应该注意internal data formats之类的事情。

答案 2 :(得分:0)

取决于您的需要。您是否只需要一个缓冲区,而不关心它最初有什么?使用GetMem。

  

GetMem在堆上分配给定大小的块,并返回   参数P中此内存的地址。已分配的字节   缓冲区未设置为零。要处置缓冲区,请使用FreeMem。如果   没有足够的内存来分配块,   引发EOutOfMemory异常。

     

注意:如果需要将内存初始化为零,请使用AllocMem   代替。

如果您的逻辑希望该缓冲区的所有字节设置为零,请使用AllocMem。

  

AllocMem在堆上分配给定大小的块,并返回   该内存的地址。设置分配缓冲区中的每个字节   归零。要处置缓冲区,请使用FreeMem。如果还不够   可用于分配块的内存,EOutOfMemory异常为   提出。

     

注意:如果不需要将内存初始化为零,则更多   而是使用GetMem高效。

//以及我是否需要在使用完内存后最终确定内存? 通常,在谈论内存分配时,应该始终释放您分配的内存。

很少有例外-

  • 引用对象计数时
  • 当另一个对象照顾一个对象并将其释放时