C Memory Pool

Definition

A memory pool (or fixed-block allocator) is a custom memory management technique where a large contiguous region is pre-allocated and subdivided into uniform fixed-size chunks. Allocation and deallocation operate in O(1) time by maintaining a free list of unused blocks, eliminating heap fragmentation, reducing system call overhead, and providing deterministic execution latency.

Architecture & Mechanics

ComponentBehavior
Pre-allocationSingle malloc, mmap, or aligned_alloc reserves the entire pool at initialization
Fixed Block SizeAll chunks are identical. Size is chosen to fit the target data structure plus alignment padding
Embedded Free ListFreed blocks store a next pointer in their first bytes. When allocated, this space holds user data
O(1) Operationsalloc = pop head of free list. free = push head of free list. No search or coalescing required
No ExpansionPool capacity is fixed. Returns NULL when exhausted. Cannot realloc individual blocks

Implementation Example

#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
typedef struct PoolBlock {
struct PoolBlock *next;
} PoolBlock;
typedef struct MemoryPool {
void *start;
size_t block_size;
size_t total_blocks;
size_t free_count;
PoolBlock *free_list;
} MemoryPool;
bool pool_init(MemoryPool *pool, size_t block_size, size_t count) {
// Ensure block can store the free-list pointer
if (block_size < sizeof(PoolBlock)) block_size = sizeof(PoolBlock);
pool->block_size = block_size;
pool->total_blocks = count;
pool->start = malloc(block_size * count);
if (!pool->start) return false;
pool->free_count = 0;
pool->free_list = NULL;
// Pre-link all blocks into free list
for (size_t i = 0; i < count; i++) {
PoolBlock *blk = (PoolBlock *)((char *)pool->start + i * block_size);
blk->next = pool->free_list;
pool->free_list = blk;
}
pool->free_count = count;
return true;
}
void *pool_alloc(MemoryPool *pool) {
if (!pool->free_list) return NULL; // Pool exhausted
PoolBlock *blk = pool->free_list;
pool->free_list = blk->next;
pool->free_count--;
return blk;
}
void pool_free(MemoryPool *pool, void *ptr) {
if (!ptr || !pool) return;
PoolBlock *blk = (PoolBlock *)ptr;
blk->next = pool->free_list;
pool->free_list = blk;
pool->free_count++;
}
void pool_destroy(MemoryPool *pool) {
free(pool->start);
pool->start = NULL;
pool->free_list = NULL;
}

Rules & Constraints

  • Fixed Capacity: Pool cannot grow. Exhaustion returns NULL. Plan sizing carefully.
  • No Resizing: realloc semantics are impossible. Allocate new block, copy data, free old block manually.
  • Alignment Requirement: Block size must satisfy platform alignment (typically 8 or 16 bytes). Misaligned blocks cause hardware faults or performance penalties.
  • Pool Ownership: Objects must be freed back to their originating pool. Freeing to a different pool corrupts the free list.
  • Data Overwrite on Free: The embedded next pointer overwrites the first sizeof(void*) bytes of freed memory. Never read freed blocks.
  • Thread Safety: Not thread-safe by default. Concurrent alloc/free requires mutexes, lock-free atomics, or per-thread pools.

Best Practices

  1. Size blocks explicitly: Use sizeof(struct) + alignment padding. Round up to nearest 8/16 bytes.
  2. Use alignas or stdalign.h (C11+) to enforce compile-time alignment guarantees.
  3. Poison freed blocks in debug: Fill with 0xDD or 0xDEADBEEF to catch use-after-free immediately.
  4. Group by lifetime/type: Place objects with similar allocation patterns in the same pool to maximize cache locality.
  5. Track statistics: Monitor free_count, peak usage, and exhaustion events for capacity tuning.
  6. Wrap in macros: #define POOL_ALLOC(pool) ((T *)pool_alloc(pool)) preserves type safety at call sites.
  7. Pre-allocate in init phase: Avoid pool initialization during runtime or interrupt contexts.

Common Pitfalls

  • 🔴 Block size too small: Cannot store free-list pointer → corruption on first free.
  • 🔴 Ignoring alignment: sizeof(T) may not satisfy alignment requirements → SIGBUS or undefined behavior.
  • 🔴 Cross-pool freeing: Passing pointer from Pool A to pool_free(&pool_B) corrupts both free lists.
  • 🔴 Assuming realloc works: Memory pools inherently reject resizing. Code must handle copy-and-reallocate manually.
  • 🔴 Thread race conditions: Unprotected free list updates cause list corruption, infinite loops, or crashes.
  • 🔴 Exhaustion unhandled: Failing to check NULL on allocation leads to immediate segmentation faults.
  • 🔴 Forgetting pool_destroy(): Leaks entire pre-allocated region even if all blocks were freed.

Standards & Tooling

  • Not in C Standard: Purely custom implementation pattern. No standard library equivalent.
  • Performance: O(1) alloc/free, zero syscalls post-init, predictable latency, excellent CPU cache behavior.
  • Debugging Limitations: ASan/Valgrind cannot track custom pools natively. Use wrapper macros, debug canaries, or custom alloc hooks (__malloc_hook/__free_hook deprecated but illustrative).
  • Industry Alternatives: jemalloc, tcmalloc, mimalloc implement arena/pool strategies internally. Embedded frameworks (FreeRTOS, Zephyr) provide production-grade pool APIs.
  • Modern C Support: C11 aligned_alloc(), _Alignof, and _Static_assert simplify size/alignment validation. C23 improves static analysis for custom allocators.
  • Use Cases: Game engines, high-frequency trading, real-time OS, kernel modules, embedded systems, network packet buffers, and any latency-sensitive or fragmentation-prone workload.

C Preprocessor, Macros & Compilation Directives (Complete Guide)

https://macronepal.com/aws/mastering-c-variadic-macros-for-flexible-debugging/
Explains variadic macros in C, allowing functions/macros to accept a variable number of arguments for flexible logging and debugging.

https://macronepal.com/aws/mastering-the-stdc-macro-in-c/
Explains the __STDC__ macro, which indicates compliance with the C standard and helps ensure portability across compilers.

https://macronepal.com/aws/c-time-macro-mechanics-and-usage/
Explains the __TIME__ macro, which provides the compilation time of a program and is often used for logging and debugging.

https://macronepal.com/aws/understanding-the-c-date-macro/
Explains the __DATE__ macro, which inserts the compilation date into programs for tracking builds.

https://macronepal.com/aws/c-file-type/
Explains the __FILE__ macro, which represents the current file name during compilation and is useful for debugging.

https://macronepal.com/aws/mastering-c-line-macro-for-debugging-and-diagnostics/
Explains the __LINE__ macro, which provides the current line number in source code, helping in error tracing and diagnostics.

https://macronepal.com/aws/mastering-predefined-macros-in-c/
Explains all predefined macros in C, including their usage in debugging, portability, and compile-time information.

https://macronepal.com/aws/c-error-directive-mechanics-and-usage/
Explains the #error directive in C, used to generate compile-time errors intentionally for validation and debugging.

https://macronepal.com/aws/understanding-the-c-pragma-directive/
Explains the #pragma directive, which provides compiler-specific instructions for optimization and behavior control.

https://macronepal.com/aws/c-include-directive/
Explains the #include directive in C, used to include header files and enable code reuse and modular programming.

HTML Online Compiler
https://macronepal.com/free-html-online-code-compiler/

Python Online Compiler
https://macronepal.com/free-online-python-code-compiler/

Java Online Compiler
https://macronepal.com/free-online-java-code-compiler/

C Online Compiler
https://macronepal.com/free-online-c-code-compiler/

C Online Compiler (Version 2)
https://macronepal.com/free-online-c-code-compiler-2/

Node.js Online Compiler
https://macronepal.com/free-online-node-js-code-compiler/

JavaScript Online Compiler
https://macronepal.com/free-online-javascript-code-compiler/

Groovy Online Compiler
https://macronepal.com/free-online-groovy-code-compiler/

J Shell Online Compiler
https://macronepal.com/free-online-j-shell-code-compiler/

Haskell Online Compiler
https://macronepal.com/free-online-haskell-code-compiler/

Tcl Online Compiler
https://macronepal.com/free-online-tcl-code-compiler/

Lua Online Compiler
https://macronepal.com/free-online-lua-code-compiler/

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper