Why did I get interested in the subject ? Because when using cmem, MemSize returns exactly what was requested
(but that might be because cmem can't look inside the libc allocator. It can only works through its abstraction)
cmem CAN look allocated size in most of the malloc libraries used. (See numerous discussions with Grumpy)
That, I tested against windows malloc and WinHeap. The funny thing is that only Windows heap announces the HeapSize function as supported. Other implementations are very vague as to it being durably supported.
BUT reaching the MemSize in any of the malloc's is a very long path if you trace the assembler whereas cmem stores it at a very quickly accessible negative offset relative to the getmem pointer. That's what is useful for AnsiStrings.
The only thing that might improve speed when using cmem would be to round up the memory request .
My customized FPC 3.2.2 has in .\3.2.2-git\rtl\inc\astrings.inc
const
RoundUp = SizeUInt(8); // Chunk up to 8 bytes block
Rounding = SizeUInt(not 8); // Mask size
AnsiUpWithOffset = AnsiFirstOff + SizeOf(char) + RoundUp;
{$ifndef FPC_HAS_NEWANSISTR}
{$define FPC_HAS_NEWANSISTR}
Function NewAnsiString(Len : SizeInt) : Pointer;
{
Allocate a new AnsiString on the heap.
initialize it to zero length and reference count 1.
}
Var
P : Pointer;
begin
{ request a multiple of 16 because the heap manager alloctes anyways chunks of 16 bytes }
// GetMem(P,Len+(AnsiFirstOff+sizeof(char)));
GetMem(P, (Len+AnsiUpWithOffset) and Rounding);
If P<>Nil then
That may (maybe not ...) help a bit cmem usage by retarding need to grab a bigger block for a reallocated string, except malloc when asked more memory for a extended reallocation will first check if the allocated chunck is large enough.