Thanks to visit codestin.com
Credit goes to github.com

Skip to content

A single-header C/C++ memory suite featuring Arena, Pool, and Debug allocators for high-performance systems.

License

Notifications You must be signed in to change notification settings

z-libs/zalloc.h

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zalloc.h

zalloc.h is a single-header, high-performance memory management suite for C/C++.

It unifies three specialized allocators, Arenas (Linear), Pools (Fixed-Block), and Debug (Leak Detection), into a cohesive API. It is designed to replace standard malloc/free in systems where performance, cache locality, and predictable lifetimes are critical.

Unlike general-purpose allocators that must handle fragmentation and thread safety at a high cost, zalloc provides specialized tools for specific patterns: linear data processing (Arenas) and node-based structures (Pools).

Features

  • Z-ARENA (Linear Allocator):

    • Zero-Overhead: Allocations are just a pointer increment.
    • Instant Cleanup: Free millions of objects in $O(1)$ by resetting the arena.
    • Cache Friendly: Data is packed sequentially in memory blocks.
    • Ideal For: Per-frame data, request handling, parsing, loading levels.
  • Z-POOL (Fixed-Block Allocator):

    • No Fragmentation: Slices memory into perfect fixed-size slots.
    • $O(1)$ Operations: Allocation and Free take constant time (free-list pop/push).
    • Ideal For: Graphs, Linked Lists, ECS Entities, and Stable Maps.
  • Z-DEBUG (Leak Detector):

    • Drop-in Replacement: Wraps standard allocators to track file/line info.
    • Buffer Guard: Detects buffer overflows (canaries) and double-frees.
    • Leak Reporting: Prints a detailed report of leaked blocks on exit.
  • Zero Dependencies: No linking required. Just drop it in and go.

Installation

  1. Copy zalloc.h to your project's include folder.
  2. Create one C file to hold the implementation:
// zalloc.c
#define ZALLOC_IMPLEMENTATION
#include "zalloc.h"

You can also do this directly from your source files without creating a new one.

Usage

Z-ARENA (Linear Allocator)

Arenas are the fastest way to manage memory for temporary tasks.

#include "zalloc.h"

void process_request()
{
    // Initialize.
    zarena scratch;
    zarena_init(&scratch);

    // Allocate rapidly (no free needed per item).
    int *data = zarena_alloc(&scratch, 100 * sizeof(int));
    char *str = zarena_alloc(&scratch, 64);
    
    // Realloc (Optimized to extend in-place if possible).
    data = zarena_realloc(&scratch, data, 100*4, 200*4);

    // Instant Cleanup (Frees all blocks at once).
    zarena_free(&scratch);
}

Tip: Use zarena_reset(&scratch) to keep the memory blocks allocated but mark them as empty. This effectively makes memory allocation "free" for the next frame/request.

Z-POOL (Fixed-Block)

Pools are mathematically optimal for systems where you allocate and free many items of the same size.

#include "zalloc.h"

struct Node
{
    int id;
    float x, y;
};

void game_loop()
{
    // Initialize pool for 'struct Node', 100 items per block.
    zpool entities;
    zpool_init(&entities, sizeof(struct Node), 100);

    // Allocate (O(1)).
    struct Node *n1 = zpool_alloc(&entities);
    struct Node *n2 = zpool_alloc(&entities);

    // Free individually (O(1)) - Returns slot to free list.
    zpool_recycle(&entities, n1);

    // Cleanup everything.
    zpool_free(&entities);
}

Z-DEBUG (Leak Detector)

Use this module during development to catch leaks and corruption.

#include "zalloc.h"

void debug_mode()
{
    // Use macros to auto-capture File and Line.
    void *p = zdebug_malloc(100);
    
    // ... forgot to free p ...

    // Print report.
    size_t leaks = zdebug_print_leaks();
    // Output: 
    // [Leak] 100 bytes at 0x... (alloc: main.c:15).
}

API Reference

Z-ARENA (Linear Allocator)

Function Description
zarena_init(zarena *a) Initializes the arena structure.
zarena_alloc(zarena *a, size_t size) Allocates size bytes. Returns NULL on failure.
zarena_alloc_zero(zarena *a, size_t size) Allocates and zero-initializes memory (like calloc).
zarena_alloc_align(zarena *a, size_t size, size_t align) Allocates memory with specific alignment (must be power of 2).
zarena_realloc(zarena *a, void *ptr, size_t old_sz, size_t new_sz) Resizes memory. Optimized if ptr was the last allocation.
zarena_reset(zarena *a) Resets usage counters but keeps allocated blocks for reuse. Fast clear.
zarena_free(zarena *a) Frees all memory blocks and resets the struct.

Z-POOL (Fixed-Block Allocator)

Function Description
zpool_init(zpool *p, size_t item_size, size_t per_block) Initializes pool for items of item_size.
zpool_alloc(zpool *p) Returns a pointer to a free slot. $O(1)$.
zpool_recycle(zpool *p, void *ptr) Returns a slot to the free list. $O(1)$.
zpool_free(zpool *p) Frees all underlying memory blocks.

Z-DEBUG (Leak Detector)

Function Description
zdebug_malloc(size_t size) Allocates memory with header tracking file/line.
zdebug_calloc(size_t n, size_t size) Allocates zero-initialized tracked memory.
zdebug_realloc(void *ptr, size_t size) Reallocates tracked memory. Checks canaries/magic.
zdebug_free(void *ptr) Frees memory. Validates guard bytes/magic before freeing.
zdebug_print_leaks(void) Prints a summary of all currently allocated blocks to stderr.
zdebug_register_atexit(void) Registers zdebug_print_leaks to run automatically when the program exits.

Integration with z-libs

zalloc was designed to power the z-libs ecosystem. You can override the memory backend of the other libraries to use an Arena or Pool.

Example: Map on an Arena

This makes map_free instantaneous and puts all map buckets into contiguous cache lines.

// Define global context for the macros.
static zarena *g_map_arena = NULL;

// Override zmap memory macros.
#define Z_MAP_MALLOC(sz)      zarena_alloc(g_map_arena, sz)
#define Z_MAP_CALLOC(n, sz)   zarena_alloc_zero(g_map_arena, (n)*(sz))
#define Z_MAP_REALLOC(p, sz)  zarena_realloc(g_map_arena, p, 0, sz)
#define Z_MAP_FREE(p)         /* No-op: Arena handles free. */

#include "zmap.h"
// ... Register types ...

int main()
{
    zarena a; 
    zarena_init(&a);
    g_map_arena = &a; // Set context.

    // Map uses arena memory automatically.
    map_IntInt m = map_init(IntInt, NULL, NULL);
    map_put(&m, 1, 100);

    // Frees the map buckets instantly.
    zarena_free(&a); 
}

Configuration

You can configure zalloc behavior by defining these macros before including the header.

Macro Description Default
ZALLOC_ARENA_ONLY Only compile the Arena module (saves binary size). Disabled
ZALLOC_POOL_ONLY Only compile the Pool module. Disabled
ZALLOC_DEBUG_ONLY Only compile the Debug module. Disabled
Z_MALLOC, Z_FREE Override the underlying backend (e.g., use OS calls directly). stdlib.h
ZARENA_DEFAULT_BLOCK_SIZE Initial size of arena blocks in bytes. 4096
ZDEBUG_LOCK Define mutex lock for thread-safe debug logging. No-op

License

MIT License. See LICENSE for details.

About

A single-header C/C++ memory suite featuring Arena, Pool, and Debug allocators for high-performance systems.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

  •  

Packages

 
 
 

Contributors