Hello,
I am a little confused about the heap usage for a PChar variable. Different programs show different results. In the documentation I read, that (on a 32 bit system) the heap is allocated in blocks of 16 bytes. So I expected e.g. 16 bytes heap usage for PChars with the length from 0 to 15 (because of the trailing zero byte) and 32 bytes heap usage for PChars with the length from 16 to 31. But this is not true, as 'program1' shows:
{$mode Delphi} {$H+}
program program1;
uses strings;
var s: string[200];
pc: pchar;
h1,h2: TFPCHeapStatus;
i: integer;
begin
for i:=0 to 50 do
begin
s:=space(i);
h1:=GetFPCHeapStatus;
pc:=StrAlloc(length(s)+1);
StrPCopy(pc,s);
h2:=GetFPCHeapStatus;
writeln(i, ' ', h2.CurrHeapUsed-h1.CurrHeapUsed);
StrDispose(pc);
end;
end.
We have 16 bytes heap usage for PChars with the length from 0 to 11 and 32 bytes for PChars with the length from 12 to 27. So there seems always to be a 'hidden consumer' who takes 4 bytes.
But in another example 'program2', which copies PChars from Ansistrings, we have an other picture:
{$mode Delphi} {$H+}
program program2;
uses sysutils;
var SR: TSearchRec;
pc: pchar;
h1,h2: TFPCHeapStatus;
e: longint;
begin
e:=FindFirst('*.*', faAnyFile, SR);
while e=0 do
begin
h1:=GetFPCHeapStatus;
pc:=StrNew(pChar(SR.name));
h2:=GetFPCHeapStatus;
writeln(length(pc):2, ' ', h2.CurrHeapUsed-h1.CurrHeapUsed, ' ', pc);
StrDispose(pc);
e:=FindNext(SR);
end;
FindClose(SR);
end.
Here we have 16 bytes heap usage for PChars with the length from 0 to 7 and 32 bytes for PChars with the length from 8 to 23. So here seems always to be a hidden consumer who takes 8 bytes!
But the reason for the difference is not the Ansistring source: 'Program3' copies also PChars from Ansistrings with StrNew(), but is more like 'program1' and has the same heap usage with a hidden consumer of only 4 bytes:
{$mode Delphi} {$H+}
program program3;
uses strings;
var s: Ansistring;
pc: pchar;
h1,h2: TFPCHeapStatus;
i: integer;
begin
for i:=0 to 50 do
begin
s:=space(i);
h1:=GetFPCHeapStatus;
pc:=StrNew(pChar(s));
h2:=GetFPCHeapStatus;
writeln(i, ' ', h2.CurrHeapUsed-h1.CurrHeapUsed);
StrDispose(pc);
end;
end.
Please can samebody explain to me who this 'hidden' consumer is (something of the heap management?) and why/when he needs sometimes 4 and sometimes 8 bytes? If there is any documentation about that please give me a link. Thanks in advance.