My plan is to allocate a fixed amount of static memory at initialization (a few MBs), and use a stack allocator for quick temporary buffers. The idea is to avoid calls to malloc()
for these kinds of temporary buffers (should be safer this way), but still being able to return it from a function (and then freed) if needed, which I otherwise wouldn't be able to with local arrays.
An allocator based on a stack sounded great for this use case, and should also be quite fast since we're only incrementing a stack pointer and calling memset()
to zero out the space.
The data I'll be storing on the stack will always be of type uint8_t, so the allocator assumes that's what we want and returns a uint8_t*
instead of a void*
like malloc()
does.
#include <stdint.h>
#include <string.h>
// Convert megabytes to bytes.
#define MB(x) (x * 1024 * 1024)
// Default size: 2 MB.
static uint8_t Stack[MB(2)];
// Points to the next available memory address.
static uint8_t *StackPointer = Stack;
int32_t GetStackUsage()
{
// Return the amount of memory used.
return StackPointer - Stack;
}
int32_t GetStackFree()
{
// Return the amount of available memory.
return sizeof(Stack) - GetStackUsage();
}
uint8_t *Alloc(int32_t length)
{
// Return a null pointer, if memory requested is less than 1 byte.
if (length < 1) return NULL;
// Return a null pointer, if there is not enough memory left on the stack.
if (StackPointer + length > Stack + sizeof(Stack)) return NULL;
// Get a pointer to the next available address.
uint8_t *memory = StackPointer;
// Zero out the memory.
memset(memory, 0, length);
// Increment stack pointer.
StackPointer += length;
return memory;
}
void Dealloc(uint8_t *memory)
{
// Double free is not a good idea.
if (memory == NULL) return;
// Reset stack pointer.
StackPointer = memory;
}