I'm reverse-engineering an older game that was probably written in C or C++. I found a function that, when it fails, loads one of several strings such as "Could not create main heap!!", "Could not create menu heap!!", "Could not create level heap!!", or "Could not create level connector heap!!", depending on where it was called.
I've started mapping the memory structure and the other functions that reference it, but I'm still unsure what I'm looking at. When I searched for "heap," most explanations described a tree-based data structure commonly implemented with an array. The structure in this game appears more complicated than that. Are those explanations describing a different kind of heap, and what does "heap" probably mean in this context?
4 Answers
One correction to some simplified explanations: ordinary local variables are not automatically stored on the heap, and heap memory is not automatically garbage-collected. A local variable may live in a register or on the stack, while dynamically allocated memory usually remains allocated until the program explicitly frees it or uses a garbage collector. In a C or C++ game, explicit cleanup or custom pool management is especially likely.
There are two unrelated meanings of “heap.” A heap data structure is the tree-like priority-queue structure often stored in an array. A memory heap is an area or pool from which a program obtains dynamically allocated memory while it runs.
The error messages are referring to the second meaning. The game may be creating separate allocation pools for the main program, menus, levels, and so on. Those could be general-purpose heaps or custom arenas managed by the game. The structure you found is therefore likely allocator metadata rather than a heap data structure.
The names suggest subsystem-specific memory management. For example, a level heap might be an arena reserved for objects loaded during a level, while destroying the level could free the whole arena at once instead of freeing every object individually. Such an allocator may contain block lists, free lists, alignment information, sizes, and bookkeeping fields, which would explain why the structure looks more complicated than an array-based priority queue.
The strings alone can’t prove the exact design. Follow the code that creates the structure, reserves or commits memory, hands out blocks, and resets or destroys it. Those call sites should reveal whether it is an arena, a general allocator, or a wrapper around the operating system’s memory functions.
A memory heap is used for data whose lifetime or size isn’t conveniently tied to one function call. In C, calls such as malloc allocate from some allocator; in C++, new typically does the same. When the data is no longer needed, it must be released with free or delete, unless the program uses another ownership system.
The stack is a separate area commonly used for function calls, parameters, and local variables. The exact implementation depends on the compiler and operating system, so don’t assume every allocation or local variable has one universal location.

Also, failing to create one of these named heaps does not necessarily mean the entire machine is out of memory. The game may have hit an allocation limit, failed to reserve a contiguous region, or rejected a configuration specific to that subsystem.