From e0f0bb0713c45de883456f50a14558352f06cec9 Mon Sep 17 00:00:00 2001 From: Warwick Date: Mon, 24 Nov 2025 11:18:19 +0000 Subject: [PATCH] Remove dangling pointers on arena parents --- src/arena_allocator.c | 12 +++++++++--- src/arena_allocator.h | 3 +-- src/main.c | 4 ++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/arena_allocator.c b/src/arena_allocator.c index 86057df..d11a6e3 100644 --- a/src/arena_allocator.c +++ b/src/arena_allocator.c @@ -26,7 +26,7 @@ Arena *arena_init(Arena *parent, size_t capacity) { if (parent != NULL) { // Allocate new arena in parent to reduce likelyhood of loss Arena *current_arena = arena_alloc(parent, sizeof(Arena)); - *current_arena = (Arena){.is_root = false, + *current_arena = (Arena){.parent = parent, .begin = region, .end = region, .child = NULL, @@ -46,7 +46,7 @@ Arena *arena_init(Arena *parent, size_t capacity) { // Create root of arena tree Arena *arena = malloc(sizeof(Arena)); - *arena = (Arena){.is_root = true, + *arena = (Arena){.parent = NULL, .begin = region, .end = region, .child = NULL, @@ -76,9 +76,15 @@ void arena_deinit(Arena *arena) { arena->begin = NULL; arena->end = NULL; - if (arena->is_root) { + + // If we're the tree root free us from malloc + if (arena->parent == NULL) { free(arena); + return; } + + // Now that we have no descendants tell our parent of our death + arena->parent->child = arena->sibling; } void *arena_alloc(Arena *arena, size_t size) { diff --git a/src/arena_allocator.h b/src/arena_allocator.h index 6dbe772..0c48a10 100644 --- a/src/arena_allocator.h +++ b/src/arena_allocator.h @@ -1,6 +1,5 @@ #pragma once -#include #include typedef struct Region_s Region; @@ -13,7 +12,7 @@ struct Region_s { typedef struct Arena_s Arena; struct Arena_s { - bool is_root; + Arena *parent; Arena *child; Arena *sibling; Region *begin; diff --git a/src/main.c b/src/main.c index a0404d2..5dae4d4 100644 --- a/src/main.c +++ b/src/main.c @@ -25,8 +25,12 @@ int main(int argc, char *argv[]) { Arena *child_arena = arena_init(global_arena, 0); Arena *sibling_arena = arena_init(global_arena, 0); Arena *grandchild_arena = arena_init(child_arena, 0); + Arena *greatgrandchild_arena = arena_init(grandchild_arena, 0); + Arena *greategreatgrandchild_arena = arena_init(greatgrandchild_arena, 0); printf("deinit test\n"); + arena_deinit(greatgrandchild_arena); + arena_deinit(global_arena); printf("tests complete\n");