Class StackAllocator¶
Defined in File stack_allocator.h
Class Documentation¶
-
class StackAllocator¶
Bump/linear allocator providing O(1) allocation via pointer increment.
StackAllocator maintains a contiguous buffer and a ‘top’ marker. Allocation simply increments the top pointer (bounds-checked), making it extremely fast compared to general-purpose allocators. This is ideal for temporary allocations with similar lifetimes, such as per-frame data in game engines.
The key feature is marker-based bulk deallocation: capture a marker with get_marker(), perform any number of allocations, then free_to_marker() to instantly free everything allocated since that marker by resetting the top pointer.
Individual free() is supported but only efficient for LIFO (stack) order. The allocator tracks allocations in an internal map, so marker-based freeing is preferred for performance.
Thread Safety: NOT thread-safe. Designed for single-threaded contexts where one thread owns the allocator for its temporary allocations.
Example - Per-frame temporary allocations:
StackAllocator frame_alloc(1024 * 1024); // 1MB buffer void process_frame() { auto marker = frame_alloc.get_marker(); // Allocate temporary data for this frame auto* entities = frame_alloc.alloc<EntityList>(100); auto* transform_buffer = frame_alloc.alloc<Transform>(entities->size()); // ... use data throughout frame processing ... // Free all frame allocations instantly frame_alloc.free_to_marker(marker); }
Important Notes:
Default size is 1KB (see implementation) - size appropriately for your use case
Allocation throws std::bad_alloc when buffer is full
Alignment: No alignment guarantees beyond byte alignment. Types requiring stricter alignment (SSE vectors, cache-line alignment) may exhibit undefined behavior. For aligned types, use aligned_alloc or posix_memalign instead.
Complements mimalloc (the global allocator) for specific high-performance patterns
See also
PoolAllocator for fixed-size object pools with arbitrary free/reuse patterns
See also
BufferedAllocator for multi-frame buffering with round-robin StackAllocators
Public Types
-
using marker = size_t¶
Type alias for position markers used by get_marker() and free_to_marker(). Represents a position in the stack’s buffer (offset in bytes from buffer start).
Public Functions
-
StackAllocator()¶
Constructs the stack allocator with default size
-
explicit StackAllocator(size_t total_size)¶
Constructs the stack allocator with the specified total size.
- Parameters:
total_size – Total size of the stack allocator in bytes.
-
void *alloc(size_t size)¶
Allocates a given size from the top of the stack
- Parameters:
size – The size to allocate
- Returns:
A pointer to the beginning of the allocated memory
-
template<typename T, typename ...Args>
inline T *alloc(Args&&... args)¶ Allocates memory and constructs an object of type T
- Template Parameters:
T – The type of object to allocate
Args – Constructor argument types
- Parameters:
args – Constructor arguments
- Returns:
Pointer to the new object
-
template<typename T>
inline void free(T *p)¶ Destroys and frees an object of type T
- Template Parameters:
T – The type of object to free
- Parameters:
p – Pointer to the object
-
void free(void *p)¶
Frees an allocation made by this stack allocator.
- Parameters:
p – The pointer to the memory to free. This must be a pointer allocated by this stack allocator.
-
size_t get_size() const¶
Gets the total size of the stack allocator.
- Returns:
The size of the stack in bytes.
-
void free_to_marker(marker m)¶
Frees all allocations made after the specified marker.
This instantly resets the ‘top’ pointer to the marker position, freeing all memory allocated since get_marker() was called. This is the preferred deallocation method for bulk freeing as it has zero iteration cost.
WARNING: This does not update the internal allocations map. Do not call free() on individual allocations made after this marker - the behavior is undefined. Use marker-based deallocation exclusively for bulk freeing, or use clear() to reset both the top pointer and allocations map.
- Parameters:
m – The marker obtained from get_marker(). Must be a valid marker from this allocator instance. Markers are invalidated by resize() or clear() operations.
-
void clear()¶
Clears the entire stack
-
void resize(size_t new_size)¶
Resizes the stack allocator to a new size. This will clear the current allocations and reset the stack.
- Parameters:
new_size – The new size of the stack in bytes.