From 57329340e27b7cef753203acf302a29809230a6f Mon Sep 17 00:00:00 2001 From: Cristian Gora Date: Tue, 7 Jul 2026 06:40:47 +0200 Subject: [PATCH] v1.2.2 --- arena.h | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/arena.h b/arena.h index be6b766..144811f 100644 --- a/arena.h +++ b/arena.h @@ -1,4 +1,4 @@ -// arena.h - v1.2.1 - MIT License +// arena.h - v1.2.2 - MIT License // single header library for region-based memory management. // // [License and changelog] @@ -21,18 +21,19 @@ // Note: every compile-time option listed here should be configured before // the #include "arena.h" // -// #define ARENA_REGION_CAPACITY new_region_capacity_in_bytes (4096) +// #define ARENA_REGION_CAPACITY new_region_capacity_in_bytes (8*1024) // // This macro defines the default capacity for arena regions. // -// #define ARENA_REGION_GROWTH_FACTOR new_region_growth_factor (1.5f) +// #define ARENA_REGION_GROWTH_FACTOR new_region_growth_factor (2) // // This macro defines the growth factor of the capacity for every // subsequent region in all arenas. // -// #define ARENA_ALIGNMENT alignment (8) +// #define ARENA_ALIGNMENT alignment (alignof(max_align_t)) // // This macro defines the memory alignment used for allocations. +// Must be a power of two. // // #define ARENA_NO_ASSERT // @@ -159,7 +160,7 @@ int main(void) #endif // ARENA_REGION_CAPACITY #ifndef ARENA_REGION_GROWTH_FACTOR -# define ARENA_REGION_GROWTH_FACTOR 1.5f +# define ARENA_REGION_GROWTH_FACTOR 2 #endif // ARENA_REGION_GROWTH_FACTOR #ifndef ARENA_ALIGNMENT @@ -300,23 +301,29 @@ void *arena_alloc(Arena *a, size_t size) return NULL; } - // Ensure memory alignment of requested size - size = arena__align(size); - // Check for overflow if (size > SIZE_MAX - sizeof(Arena_Region)) { ARENA_ASSERT(false && "Requested size too large"); return NULL; } + // Ensure memory alignment of requested size + size = arena__align(size); + // Get the next region capacity multiplied by the growth factor size_t region_capacity = (a->region_capacity == 0 ? ARENA_REGION_CAPACITY : a->region_capacity); if (a->tail != NULL) { - region_capacity = a->tail->capacity * ARENA_REGION_GROWTH_FACTOR; - // Edge case for small growth factors - if (region_capacity <= a->tail->capacity) { - region_capacity = a->tail->capacity + 1; + size_t max_cap = (SIZE_MAX / 2) - sizeof(Arena_Region); + + if (a->tail->capacity >= max_cap / (ARENA_REGION_GROWTH_FACTOR)) { + region_capacity = max_cap; + } else { + region_capacity = a->tail->capacity * (ARENA_REGION_GROWTH_FACTOR); + // Edge case for small growth factors + if (region_capacity <= a->tail->capacity) { + region_capacity = a->tail->capacity + (4 * 1024); + } } } @@ -344,7 +351,9 @@ void *arena_alloc(Arena *a, size_t size) // Find first suitable region Arena_Region *r = a->tail; + Arena_Region *last = r; while (r != NULL && size > r->capacity - r->count) { + last = r; r = r->next; } @@ -354,18 +363,19 @@ void *arena_alloc(Arena *a, size_t size) ARENA_ASSERT(false && "Region count overflow"); return NULL; } + a->tail = r; r->count += size; return r->data + r->count - size; } // If not found append a new region - a->tail->next = (Arena_Region*)ARENA_MALLOC(sizeof(*a->tail) + alloc_size); - if (a->tail->next == NULL) { + last->next = (Arena_Region*)ARENA_MALLOC(sizeof(*a->tail) + alloc_size); + if (last->next == NULL) { ARENA_ASSERT(false && "Allocation failed"); return NULL; } - a->tail = a->tail->next; + a->tail = last->next; a->tail->next = NULL; a->tail->count = size; a->tail->capacity = alloc_size; @@ -434,7 +444,7 @@ char *arena_sprintf(Arena *a, const char *fmt, ...) size_t needed = (size_t)n + 1; // If it fits commit and return - if (needed <= available) { + if (arena__align(needed) <= available) { r->count += arena__align(needed); va_end(args); return result; @@ -508,6 +518,8 @@ size_t arena__align(size_t n) /* * Revision history: * + * 1.2.2 (2026-07-07) Fix various memory problems; + * make ARENA_REGION_GROWTH_FACTOR an integer * 1.2.1 (2026-04-08) Region growth factor handling with new * ARENA_REGION_GROWTH_FACTOR macro * 1.2.0 (2026-04-08) New functions: arena_sprintf(), arena_snapshot(),