mulle_allocator_stdlib_nofree: Purpose and Usage for Static Allocation Patterns
mulle_allocator_stdlib_nofree is a singleton allocator that forwards allocation requests to the C standard library (calloc/realloc) while implementing free as a no-operation, making it ideal for static or arena allocation patterns where memory is never reclaimed individually.
The mulle-c/mulle-allocator library provides a pluggable memory management abstraction that decouples allocation strategy from application logic. The mulle_allocator_stdlib_nofree singleton serves as a specialized tool for scenarios where allocated memory lives for the entire process duration or is reclaimed in bulk by external mechanisms.
What is mulle_allocator_stdlib_nofree?
In src/mulle-allocator.c (lines 157–165), the library defines mulle_allocator_stdlib_nofree as a global constant structure:
struct mulle_allocator mulle_allocator_stdlib_nofree =
{
calloc, // allocate & zero‑initialize
realloc, // resize
no_free, // free‑operation does nothing
mulle_allocation_fail,
mulle_allocator_no_aba_abort,
NULL
};
This configuration creates an indirection layer over standard C memory functions. While allocation and resizing use the system calloc and realloc, the free member points to no_free, a stub function that discards its arguments using MULLE_C_UNUSED. Consequently, any memory obtained through this allocator remains allocated until the process terminates, regardless of free calls.
According to the documentation in assets/dox/TOC.md (lines 20–22), this allocator is explicitly designed to "allocate but never free (for static/arena patterns)".
When to Use mulle_allocator_stdlib_nofree
Use mulle_allocator_stdlib_nofree when individual deallocation is unnecessary or undesirable:
- Bootstrap phases — Initialize complex data structures during program startup that persist until process exit, eliminating deallocation overhead.
- Arena/region allocators — Build high-level allocators that manage memory in bulk; the OS reclaims all memory when the arena is destroyed or the process ends.
- Performance-critical sections — Avoid the computational cost of
freebookkeeping when object lifetimes are guaranteed to span the entire program execution. - Testing harnesses — Verify that code paths do not rely on
freebeing called, or disable leak-checking for specific test scenarios.
Do not use this allocator when individual objects must be reclaimed mid-execution, when operating under memory constraints, or when integrating with external libraries that expect free to actually release memory back to the system.
mulle_allocator_stdlib_nofree Code Examples
Basic Allocation Pattern
The following demonstrates safe allocation where the free call is harmless but ineffective:
#include <mulle-allocator/mulle-allocator.h>
int main(void)
{
// Grab the no‑free allocator singleton
struct mulle_allocator *alloc = &mulle_allocator_stdlib_nofree;
// Allocate 256 bytes — memory will never be returned to the OS
void *buf = mulle_allocator_calloc(alloc, 1, 256);
/* use buf … */
// This call is safe but performs no action
mulle_allocator_free(alloc, buf);
return 0;
}
Integration with Data Structures
Embed the allocator in structures that manage pooled memory:
struct arena_vector
{
struct mulle_allocator *allocator; // points to stdlib_nofree
void **items;
size_t count;
};
void arena_vector_init(struct arena_vector *v)
{
v->allocator = &mulle_allocator_stdlib_nofree;
v->items = mulle_allocator_malloc(v->allocator, 16 * sizeof(void *));
v->count = 0;
}
/* Adding an element — no need to free individual items later */
void arena_vector_push(struct arena_vector *v, void *elem)
{
v->items[v->count++] = elem;
}
Runtime Detection
Detect if an allocator is the no-free variant using the query helper defined in src/mulle-allocator.c (lines 46–73):
if (mulle_allocator_is_stdlib_allocator(&mulle_allocator_stdlib_nofree))
{
printf("Running with a no‑free allocator\n");
}
Runtime Detection and Safety Features
The mulle_allocator_is_stdlib_allocator() function provides a reliable way to identify when code is operating with mulle_allocator_stdlib_nofree. This is particularly useful in generic libraries that need to adapt their behavior based on allocation guarantees.
Because free is implemented as a no-op, calling mulle_allocator_free() on memory obtained from this allocator is completely safe—it prevents accidental double-free errors and eliminates risks associated with freeing memory through the wrong allocator instance. This safety property makes mulle_allocator_stdlib_nofree suitable for subsystem isolation where deallocation discipline might otherwise be error-prone.
Summary
mulle_allocator_stdlib_nofreeforwardscallocandreallocto the C standard library but ignores allfreerequests.- Located in
src/mulle-allocator.c(lines 157–165), this singleton is documented inassets/dox/TOC.mdas the allocator that "allocates but never frees". - Ideal for static initialization, arena allocation patterns, and performance-critical paths where object lifetimes match process duration.
- Safe to use because
freecalls are no-ops, preventing double-free and allocator-mismatch bugs. - Detectable at runtime via
mulle_allocator_is_stdlib_allocator()(defined insrc/mulle-allocator.clines 46–73).
Frequently Asked Questions
What happens if I call free on memory allocated with mulle_allocator_stdlib_nofree?
Nothing. The allocator's free function is implemented as no_free, a stub that silently discards its arguments. This is a deliberate safety feature that prevents double-free errors and makes the allocator harmless to use in contexts where free might be called defensively.
How do I check if my current allocator is the no-free variant at runtime?
Use the mulle_allocator_is_stdlib_allocator() function declared in src/mulle-allocator.h and implemented in src/mulle-allocator.c (lines 46–73). Pass a pointer to mulle_allocator_stdlib_nofree or any allocator instance to verify if it matches the standard library-based no-free singleton.
Can I use mulle_allocator_stdlib_nofree with third-party libraries?
Only if those libraries do not expect free to actually release memory. Since mulle_allocator_stdlib_nofree never returns memory to the system, using it with libraries that perform frequent allocations and deallocations will cause unbounded memory growth. Restrict its use to code you control or libraries designed for arena-style allocation.
Is mulle_allocator_stdlib_nofree thread-safe?
Yes, because it relies on the underlying C standard library functions (calloc and realloc), which are typically thread-safe on modern systems. However, since free is a no-op, there is no synchronization overhead for deallocation operations, making this allocator particularly efficient for concurrent allocation-heavy workloads with static lifetimes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →