Skip to content

Proposal: stb_membag.h — tiny batch allocator (malloc tracking + bulk free) #1895

@yairlenga

Description

@yairlenga

I’d like to propose a small stb-style utility header tentatively named stb_membag.h.

Summary

stb_membag is a minimal “batch allocator” that tracks malloc allocations and frees them all at once.
It’s intended for functions or short-lived scopes that perform multiple allocations and want simple, safe cleanup without error-path complexity.

Conceptually it sits between raw malloc/free and arena allocators.
Unlike arenas, it does not manage blocks or reuse memory — it simply tracks allocations and frees them in bulk.

Motivation

A common C pattern:

void f(void) {
    A *a = malloc(...);
    if ( !do_something(a) ) {
        free(a) ;
        return ... ;
    } ;
    B *b = malloc(...);
    if ( !do_something(b) ) {
        free(b) ;  free(a) ;
        return ;
    } ;
    C *c = malloc(...);
    if ( !do_something(c) ) {
        free(c) ; free(b) ; free(a) ;
        return ;
    } ;

    do_job(a, b, c) ;

    free(c) ; free(b) ; free(a) ;
    return ... ;
}

Error handling becomes verbose and fragile.

With stb_membag:

void f(void) {
    stbmb_var bag;
    stbmb_init(bag);

    A *a = stbmb_malloc(bag, ...);
    if ( !do_something(a) ) {
        stbmb_free_all(bag) ;
        return ... ;
    } ;
    B *b = stbmb_malloc(bag, ...);
    if ( !do_something(b) ) {
        stbmb_free_all(bag) ;
        return ;
    } ;
    C *c = stbmb_malloc(bag, ...);
    if ( !do_something(c) ) {
        stbmb_free_all(bag) ;
        return ;
    } ;

    do_job(a, b, c) ;

    stbmb_free_all(bag) ;
    return ... ;
}

This keeps allocation simple and guarantees cleanup on all paths.

Scope ### (intentionally minimal)

  • track malloc pointers
  • bulk free (free_all)
  • optional mark/release (free since mark)
  • no arenas / no blocks / no reuse
  • no threading

Implementation is header-only and small (~200–300 LOC).
Internally it uses a realloc-grown pointer array.

Example API

typedef struct stbmb stbmb, stbmb_var[1];
typedef struct stbmb_mark stbmb_mark;

void  stbmb_init(stbmb *b);
void  stbmb_free_all(stbmb *b);

void* stbmb_malloc(stbmb *b, size_t size);
void* stbmb_zalloc(stbmb *b, size_t size);
void *stbmb_callloc(stmbm *b, int n, size_t sz) ;

stbmb_mark stbmb_mark(const stbmb *b);
void       stbmb_release(stbmb *b, stbmb_mark m);

Fit for stb

This fills a small but common gap:

  • simpler than arenas
  • safer than raw malloc
  • trivial integration (single header)
  • broadly useful in C utilities, loaders, parsers, tools

Before preparing a PR, I wanted to check whether this kind of utility fits stb’s scope.

Thanks,
Yair

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions