I know C powers server software though so it must be viable but maybe computers these days have so much memory it's not likely to get into heap fragmentation issues? I can also imagine a memory arena would be good with a stack as you could free the memory in batches in the same order as it was allocated in many instances.
C and (modern) Pascal programs are very differently. As I have already mentioned in a previous thread, in Pascal you will often see people creating classes (which require memory allocation) for alot of ver small things. For example I have just written this function today:
var
JSONData: TJSONObject;
ProfilesFile: String;
JSONText: String;
fs: TFileStream;
begin
ProfilesFile := ConcatPaths([ExtractFileDir(ParamStr(0)), 'profiles.json']);
JSONData := ToJSON(FHeaderProfiles, FFileTypeProfiles);
try
fs := TFileStream.Create(ProfilesFile, fmCreate);
try
JSONText := JSONData.FormatJSON;
fs.WriteBuffer(JSONText[0], JSONText.Length);
finally
fs.Free;
end;
finally
JSONData.Free;
end;
As you can see, it creates a temporary TFileStream to write to the file. This requires an allocation which will be very short lived. This is how writing to a file looks in C++:
std::ifstream fs{"file.txt"};
fs << "Hello World!\n";
Note that this class is created on the stack, so no allocation is required.
So in Pascal you have a lot of small to medium sized allocations that are very short lived, something you typically avoid in C++. In C as a fully procedural language with manual memory management you typically use even less heap allocated memory (e.g. you often use stack buffers for strings because dynamic creation and destruction is annoying)
The C Memory manager is optimized for typical C and C++ programs, those are very different than typical Pascal Programs. So it's not really comparable.
I didn't know that. Is there even a single memory manager for C++ or does each of the major C++ compilers provide their own memory manager also?
Both, malloc and free are functions implemented in the LibC. You usually have one LibC provided by your OS (on Unix it's a requirement by the POSIX Spec), and this is also usually quite optimized code (often containing multiple versions for different functions optimized for specific processor types). That said, you can use different LibCs, even with different compilers. You can use the GLibC, UC-LibC or Musl LibC with you GCC or Clang, all having their own implementations for malloc and free.
Clang and GCC also ship the so called Address Sanatizer (ASAN), which amongst other features contains a custom memory manager similar to FPCs HeapTrc (but also has additional annotation functionalities, making it a much more powerful tool).
So it's not even up to the compiler really, it's up to the programmer to chose what LibC they want to use.
Additionally to that, C++ has an Allocator API as well as support for custom allocators for their New and Free keywords (equivalent to new and dispose in Pascal). This allows the programmer to use different memory managers in different situations.
For example I had once worked on a program where I would create a Tree consisting of alot of Nodes, which are dynamically allocated. I constructed the tree once, and then deleted all of Nodes at once when the tree was done.
So what I did was I created a LIFO Allocator, where I allocated a huge area of memory at once, with a pointer to the start, and when a new node was allocated, I would return that pointer and then move it by the size of the node. When I was done I would not free each node individually, but just free the whole block at once.
This gave me a massive improvement in performance on the construction and teardown of that tree, something a typical heap based memory manager would be to slow for.
And it's not just new and free, pretty much all classes in the STL (standard library) can be parametrized with a custom allocator. For example std::vector (basically a List type) just takes an allocator as template parameter, which will be used to allocate the list elements.
So long story short, in C++ there is not just one Memory Manager, you can find even multiple allocators used within a single project