Разница в том, что 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
.
Но, конечно, выделение памяти вручную в куче предназначено для ("продвинутых") вещей низкого уровня; чаще всего вы этого не делаете. Если вы это сделаете, вы должны знать о таких вещах, как внутренние форматы данных .