From 1956855adf9433cdf05fdd18ce2aa9331e168ba4 Mon Sep 17 00:00:00 2001 From: seajee Date: Tue, 18 Nov 2025 18:22:02 +0100 Subject: [PATCH] v1.1.0 - New helper functions: arena_copy(), arena_strdup() --- arena.h | 67 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/arena.h b/arena.h index 01e0800..2c1f937 100644 --- a/arena.h +++ b/arena.h @@ -1,4 +1,4 @@ -// arena.h - v1.0.3 - MIT License - https://github.com/seajee/arena.h +// arena.h - v1.1.0 - MIT License // single header library for region-based memory management. // // [License and changelog] @@ -23,10 +23,10 @@ // // #define ARENA_NO_ASSERT // -// This macro disables assertions that happen when a reallocation -// fails. The disabled assertions will be replaced with a simple -// condition that returns NULL when it fails. Note that ARENA_ASSERT -// is only used in arena_alloc(). +// This macro disables assertions that happen when allocations fail. +// The disabled assertions will be replaced with a simple condition +// that returns NULL when it fails. This macro affects every function +// that returns a pointer. // // #define ARENA_REGION_CAPACITY new_region_capacity_in_bytes (4096) // @@ -34,9 +34,8 @@ // // #define ARENA_ASSERT my_assert // -// This macro defines an alternative function for assertions. In this -// library, ARENA_ASSERT is only used when arena_alloc() fails. Will -// be overwritten if ARENA_NO_ASSERT is defined. +// This macro defines an alternative function for assertions. This has +// no effect when ARENA_NO_ASSERT is defined. // // #define ARENA_REALLOC my_realloc // #define ARENA_FREE my_free @@ -53,16 +52,25 @@ // // Arena arena_create(size_t region_capacity) // -// This function initializes an arena with a specified region capacity. By -// default the region capacity is ARENA_REGION_CAPACITY, which can be -// configured by redefining it before including the header file. This function -// is not strictly necessary for initializing an arena (see example). +// This function is optional (see [Example] section): initializes an arena +// with a specified region capacity. It will override the default +// ARENA_REGION_CAPACITY. // // void *arena_alloc(Arena *a, size_t size) // // This function allocates a buffer of bytes into the specified arena // and returns it's pointer. // +// void *arena_copy(Arena *a, const void *src, size_t size); +// +// This function allocates a buffer of bytes into the arena and copies +// the contents of . +// +// char *arena_strdup(Arena *a, const char *s); +// +// This functions acts like the strdup() function but it instead allocates on +// the specified arena. It duplicates a string in the arena. +// // void arena_free(Arena *a) // // This function frees all of the regions allocated in the specified arena @@ -77,7 +85,7 @@ // Warning: this functions may cause fragmentation, consider setting an // appropriate region capacity. // -// [Note] +// [Notes] // // This library is not Thread-safe. // @@ -105,6 +113,7 @@ int main(void) #include #include +#include #ifndef ARENA_REGION_CAPACITY # define ARENA_REGION_CAPACITY (8*1024) @@ -150,6 +159,8 @@ typedef struct Arena { Arena arena_create(size_t region_capacity); void *arena_alloc(Arena *a, size_t size); +void *arena_copy(Arena *a, const void *src, size_t size); +char *arena_strdup(Arena *a, const char *s); void arena_free(Arena *a); void arena_reset(Arena *a); @@ -167,7 +178,8 @@ extern "C" { // Prevent name mangling of functions Arena arena_create(size_t region_capacity) { - Arena a = {0}; + Arena a; + memset(&a, 0, sizeof(a)); a.region_capacity = region_capacity; return a; } @@ -175,7 +187,7 @@ Arena arena_create(size_t region_capacity) void *arena_alloc(Arena *a, size_t size) { if (a == NULL || size == 0) { - ARENA_ASSERT(false && "Invalid, parameters"); + ARENA_ASSERT(false && "Invalid parameters"); return NULL; } @@ -233,6 +245,30 @@ void *arena_alloc(Arena *a, size_t size) return a->tail->data + a->tail->count - size; } +void *arena_copy(Arena *a, const void *src, size_t size) +{ + if (a == NULL || src == NULL) { + ARENA_ASSERT(false && "Invalid parameters"); + return NULL; + } + + void *copy = arena_alloc(a, size); + memcpy(copy, src, size); + + return copy; +} + +char *arena_strdup(Arena *a, const char *s) +{ + if (a == NULL || s == NULL) { + ARENA_ASSERT(false && "Invalid parameters"); + return NULL; + } + + return (char*)arena_copy(a, s, strlen(s) + 1); +} + + void arena_free(Arena *a) { if (a == NULL) { @@ -273,6 +309,7 @@ void arena_reset(Arena *a) /* * Revision history: * + * 1.1.0 (2025-11-18) New helper functions: arena_copy(), arena_strdup() * 1.0.3 (2025-09-10) Renamed parameter bytes to size in arena_alloc() * 1.0.2 (2025-09-06) Bug fixes; new ARENA_NO_ASSERT macro * 1.0.1 (2025-08-02) Prevent name mangling of functions; don't reset