Home | About | Blog | Projects | Contact

Arena Allocator

Posted: July 20, 2025

My own Arena Allocator developed to understand memory in C better

Phase 1

Requirements:

Code

Phase 1 Functions
       
        typedef struct Arena {
            uint8_t* buffer;
            size_t  offset;
            size_t  capacity;
        } Arena_t;

        Arena_t newArena(size_t capacity){
            void* buffer = malloc(capacity);
            Arena_t arena = {
                .capacity = capacity,
                .offset = 0,
                .buffer = buffer
            };
            return arena;
        }

        void *allocArena(Arena_t* arena, size_t offset){
            assert((arena->offset + offset) < (arena->capacity));
            void *buffer = arena->buffer[arena->offset];
            arena->offset += offset;
            return buffer;
        }

        void freeArena(Arena_t* arena){
            arena->capacity = 0x00;
            arena->offset = 0x00;
            free(arena->buffer);
        }

        void resetArena(Arena_t* arena){
            arena->offset = 0x00;
        }
        

Phase 2

Code

Phase 2 Functions
    
        typedef struct Arena {

            struct Arena_t* next;
            uint8_t* buffer;
            size_t  offset;
            size_t  capacity;

        } Arena_t;

        Arena_t arena_init(size_t capacity){

            void* buffer = malloc(sizeof(uint8_t) * capacity);

            Arena_t arena = {
                .capacity = capacity,
                .offset = 0,
                .buffer = buffer,
                .next = NULL
            };

            return arena;
        }

        void *allocArena(Arena_t* arena, size_t offset){

            Arena_t* current = arena;
            assert(current->capacity >= offset);

            while(!(current->offset + offset <= current->capacity)) {

                if(current->next == NULL) {
                    Arena_t* next = malloc(sizeof(Arena_t));
                    next->capacity = arena->capacity;
                    next->offset = 0;
                    next->next = NULL;
                    next->buffer = malloc(sizeof(uint8_t) * arena->capacity);
                    current->next = next;
                }
                current = current->next;
            }

            uint8_t *buffer = ¤t->buffer[current->offset];
            current->offset += offset;
            return buffer;
        }

        void freeArena(Arena_t* arena){
            free(arena->buffer);
            arena->capacity = 0;
            arena->offset = 0;
            Arena_t* current = arena->next;
            while(current != NULL) {
                Arena_t* tmp = current->next;
                free(current->buffer);
                free(current);
                current = tmp;
            }
            arena->next = NULL;
        }

        void resetArena(Arena_t* arena){
            Arena_t* current = arena;
            current->offset = 0x00;
            current = current->next;
        }

        void print_arena(Arena_t *arena){
            Arena_t* current = arena;
            int i = 1;
            while (current->next != NULL) {
                printf("%d capacity: %zu, offset: %zu, buffer ptr: %p\n", i, current->capacity, current->offset, current->buffer);
                current = current->next;
                i++;
            }
            if (current->next == NULL) {
                printf("%d capacity: %zu, offset: %zu, buffer ptr: %p\n", i, current->capacity, current->offset, current->buffer);
                current = current->next;
            }
        } 
    

← Back to blog home