Remove dangling pointers on arena parents

This commit is contained in:
Warwick 2025-11-24 11:18:19 +00:00
parent 19e27ca782
commit e0f0bb0713
3 changed files with 14 additions and 5 deletions

View file

@ -26,7 +26,7 @@ Arena *arena_init(Arena *parent, size_t capacity) {
if (parent != NULL) { if (parent != NULL) {
// Allocate new arena in parent to reduce likelyhood of loss // Allocate new arena in parent to reduce likelyhood of loss
Arena *current_arena = arena_alloc(parent, sizeof(Arena)); Arena *current_arena = arena_alloc(parent, sizeof(Arena));
*current_arena = (Arena){.is_root = false, *current_arena = (Arena){.parent = parent,
.begin = region, .begin = region,
.end = region, .end = region,
.child = NULL, .child = NULL,
@ -46,7 +46,7 @@ Arena *arena_init(Arena *parent, size_t capacity) {
// Create root of arena tree // Create root of arena tree
Arena *arena = malloc(sizeof(Arena)); Arena *arena = malloc(sizeof(Arena));
*arena = (Arena){.is_root = true, *arena = (Arena){.parent = NULL,
.begin = region, .begin = region,
.end = region, .end = region,
.child = NULL, .child = NULL,
@ -76,9 +76,15 @@ void arena_deinit(Arena *arena) {
arena->begin = NULL; arena->begin = NULL;
arena->end = NULL; arena->end = NULL;
if (arena->is_root) {
// If we're the tree root free us from malloc
if (arena->parent == NULL) {
free(arena); 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) { void *arena_alloc(Arena *arena, size_t size) {

View file

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
typedef struct Region_s Region; typedef struct Region_s Region;
@ -13,7 +12,7 @@ struct Region_s {
typedef struct Arena_s Arena; typedef struct Arena_s Arena;
struct Arena_s { struct Arena_s {
bool is_root; Arena *parent;
Arena *child; Arena *child;
Arena *sibling; Arena *sibling;
Region *begin; Region *begin;

View file

@ -25,8 +25,12 @@ int main(int argc, char *argv[]) {
Arena *child_arena = arena_init(global_arena, 0); Arena *child_arena = arena_init(global_arena, 0);
Arena *sibling_arena = arena_init(global_arena, 0); Arena *sibling_arena = arena_init(global_arena, 0);
Arena *grandchild_arena = arena_init(child_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"); printf("deinit test\n");
arena_deinit(greatgrandchild_arena);
arena_deinit(global_arena); arena_deinit(global_arena);
printf("tests complete\n"); printf("tests complete\n");