pointers-memory · intermediate · ~15 min
Implement scratchpad bump allocation with watermark checkpointing and bulk deallocation.
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.
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);
arena_init: initializes a->buffer = buffer, a->capacity = capacity, and a->offset = 0.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.arena_get_mark: returns current a->offset (or 0 if a == NULL).arena_rewind: if a != NULL and mark <= a->offset, set a->offset = mark.a: arena pointer; buffer: memory slab; capacity: slab size; sz: requested bytes; mark: rewind offset.
arena_alloc returns allocated pointer or NULL. arena_get_mark returns size_t.
C11 freestanding bump allocation. Bulk-free via watermark.
#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;
}
Allowing offset + sz to wrap around or exceed capacity; rewinding to a mark greater than offset.
Allocating 0 bytes returns NULL; allocating more than remaining capacity returns NULL; rewinding to 0 resets the arena.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.