在Delphi中,我看到了几个类似的函数,可以用来分配内存,比如GetMem和AllocMem。他们之间有什么不同?
我阅读了文档,只发现GetMem不会在分配后初始化内存,而AllocMem会初始化内存。
那么在调用GetMem之后是否需要初始化内存呢?医生同意了。但是我在一些Delphi源代码中看到了它们不称为Initialize的代码。
我是否需要在使用完内存后完成它的最后定稿?我在一些Delphi源代码中看到,它们确实如此,但有些事情他们不做。
谢谢
发布于 2019-05-21 07:40:50
逻辑看起来很简单--如果需要零初始化缓冲区,可以使用AllocMem。
如果您在任何情况下都使用自己的数据填充缓冲区,并且永远不使用默认内容,则可以使用GetMem。
发布于 2019-05-21 07:53:25
区别在于,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将新分配的缓冲区中的每个字节设置为0。
但是,当然,在堆上手动分配内存是为了(“高级”)低级别的东西;大多数情况下,您不会这样做。如果您这样做,您应该知道像内部数据格式这样的事情。
发布于 2019-05-21 07:53:47
取决于你的需要。你是否只需要一个缓冲区,而不关心它最初拥有什么?使用GetMem。
GetMem在堆上分配一个给定大小的块,并以参数P返回此内存的地址。分配的缓冲区的字节没有设置为零。若要释放缓冲区,请使用FreeMem。如果没有足够的内存来分配块,则会引发EOutOfMemory异常。 注意:如果内存需要零初始化,使用AllocMem代替.
如果逻辑期望缓冲区集的所有字节为零,请使用AllocMem。
AllocMem在堆上分配一个给定大小的块,并返回此内存的地址。分配缓冲区中的每个字节设置为零。若要释放缓冲区,请使用FreeMem。如果没有足够的内存来分配块,则会引发EOutOfMemory异常。 注意:如果内存不需要零初始化,则使用GetMem更有效。
//以及在使用完内存后是否需要最后确定内存?通常在谈到内存分配时,您分配的内存应该始终被释放。
很少有例外-
https://stackoverflow.com/questions/56233382
复制相似问题