pointers-memory · intermediate · ~15 min

Arena allocator with watermark rewind

Implement scratchpad bump allocation with watermark checkpointing and bulk deallocation.

Challenge

Arena (bump) allocators allocate linearly from a fixed memory slab. By saving a watermark (offset mark) before a temporary operation and rewinding back to it afterwards, scratch allocations can be freed in $O(1)$ time without individual free() calls.

Your Task

Implement:

struct arena {
    char *buffer;
    size_t capacity;
    size_t offset;
};

void arena_init(struct arena *a, char *buffer, size_t capacity);
void *arena_alloc(struct arena *a, size_t sz);
size_t arena_get_mark(const struct arena *a);
void arena_rewind(struct arena *a, size_t mark);

Rules

  1. arena_init: initializes a->buffer = buffer, a->capacity = capacity, and a->offset = 0.
  2. arena_alloc: if a == NULL, sz == 0, or a->offset + sz > a->capacity, return NULL. Otherwise, return a->buffer + a->offset, and advance a->offset += sz.
  3. arena_get_mark: returns current a->offset (or 0 if a == NULL).
  4. arena_rewind: if a != NULL and mark <= a->offset, set a->offset = mark.

Input format

a: arena pointer; buffer: memory slab; capacity: slab size; sz: requested bytes; mark: rewind offset.

Output format

arena_alloc returns allocated pointer or NULL. arena_get_mark returns size_t.

Constraints

C11 freestanding bump allocation. Bulk-free via watermark.

Starter code

#include <stddef.h>

/* The harness provides:
struct arena {
    char *buffer;
    size_t capacity;
    size_t offset;
};
*/

void arena_init(struct arena *a, char *buffer, size_t capacity) {
    (void)a; (void)buffer; (void)capacity;
}

void *arena_alloc(struct arena *a, size_t sz) {
    (void)a; (void)sz;
    return NULL;
}

size_t arena_get_mark(const struct arena *a) {
    (void)a;
    return 0;
}

void arena_rewind(struct arena *a, size_t mark) {
    (void)a; (void)mark;
}

Common mistakes

Allowing offset + sz to wrap around or exceed capacity; rewinding to a mark greater than offset.

Edge cases to handle

Allocating 0 bytes returns NULL; allocating more than remaining capacity returns NULL; rewinding to 0 resets the arena.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.