v1.1.2 Minor changes; check result of alloc in arena_copy()

This commit is contained in:
seajee
2026-01-10 17:42:14 +01:00
parent 1b7e73d3cb
commit 2d465afc7f
2 changed files with 41 additions and 32 deletions

71
arena.h
View File

@@ -1,4 +1,4 @@
// arena.h - v1.1.1 - MIT License // arena.h - v1.1.2 - MIT License
// single header library for region-based memory management. // single header library for region-based memory management.
// //
// [License and changelog] // [License and changelog]
@@ -61,6 +61,20 @@
// with a specified region capacity. It will override the default // with a specified region capacity. It will override the default
// ARENA_REGION_CAPACITY. // ARENA_REGION_CAPACITY.
// //
// void arena_free(Arena *a)
//
// This function frees all of the regions allocated in the specified arena
// which invalidates all the pointers associated with the arena. The arena can
// still be reused. If the arena was created with arena_create() the
// configured region_capacity will be retained.
//
// void arena_reset(Arena *a)
//
// This function resets an arena by keeping all of the regions allocated but
// invalidates all of the pointers associated with the specified arena.
// Warning: this functions may cause fragmentation, consider setting an
// appropriate region capacity.
//
// void *arena_alloc(Arena *a, size_t size) // void *arena_alloc(Arena *a, size_t size)
// //
// This function allocates a buffer of <size> bytes into the specified arena // This function allocates a buffer of <size> bytes into the specified arena
@@ -76,20 +90,6 @@
// This functions acts like the strdup() function but it instead allocates on // This functions acts like the strdup() function but it instead allocates on
// the specified arena. It duplicates a string in the arena. // 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
// which invalidates all the pointers associated with the arena. The arena can
// still be reused. If the arena was created with arena_create() the
// configured region_capacity will be retained.
//
// void arena_reset(Arena *a)
//
// This function resets an arena by keeping all of the regions allocated but
// invalidates all of the pointers associated with the specified arena.
// Warning: this functions may cause fragmentation, consider setting an
// appropriate region capacity.
//
// [Notes] // [Notes]
// //
// This library is not Thread-safe. // This library is not Thread-safe.
@@ -125,7 +125,7 @@ int main(void)
#endif // ARENA_REGION_CAPACITY #endif // ARENA_REGION_CAPACITY
#ifndef ARENA_ALIGNMENT #ifndef ARENA_ALIGNMENT
# define ARENA_ALIGNMENT sizeof(max_align_t) # define ARENA_ALIGNMENT alignof(max_align_t)
#endif // ARENA_ALIGNMENT #endif // ARENA_ALIGNMENT
#ifndef ARENA_NO_ASSERT #ifndef ARENA_NO_ASSERT
@@ -166,13 +166,15 @@ typedef struct Arena {
size_t region_capacity; size_t region_capacity;
} Arena; } Arena;
// Arena management
Arena arena_create(size_t region_capacity); Arena arena_create(size_t region_capacity);
void arena_free(Arena *a); void arena_free(Arena *a);
void arena_reset(Arena *a);
// Allocation other utilities
void *arena_alloc(Arena *a, size_t size); void *arena_alloc(Arena *a, size_t size);
void *arena_copy(Arena *a, const void *src, size_t size); void *arena_copy(Arena *a, const void *src, size_t size);
char *arena_strdup(Arena *a, const char *s); char *arena_strdup(Arena *a, const char *s);
void arena_reset(Arena *a);
#ifdef __cplusplus #ifdef __cplusplus
} }
@@ -212,6 +214,19 @@ void arena_free(Arena *a)
// a->region_capacity = 0; // a->region_capacity = 0;
} }
void arena_reset(Arena *a)
{
if (a == NULL) {
return;
}
for (Arena_Region *cur = a->head; cur != NULL; cur = cur->next) {
cur->count = 0;
}
a->tail = a->head;
}
void *arena_alloc(Arena *a, size_t size) void *arena_alloc(Arena *a, size_t size)
{ {
if (a == NULL || size == 0) { if (a == NULL || size == 0) {
@@ -242,7 +257,7 @@ void *arena_alloc(Arena *a, size_t size)
if (a->head == NULL) { if (a->head == NULL) {
a->head = (Arena_Region*)ARENA_MALLOC(sizeof(*a->head) + alloc_size); a->head = (Arena_Region*)ARENA_MALLOC(sizeof(*a->head) + alloc_size);
if (a->head == NULL) { if (a->head == NULL) {
ARENA_ASSERT(false && "Reallocation failed"); ARENA_ASSERT(false && "Allocation failed");
return NULL; return NULL;
} }
@@ -272,7 +287,7 @@ void *arena_alloc(Arena *a, size_t size)
// If not found append a new region // If not found append a new region
a->tail->next = (Arena_Region*)ARENA_MALLOC(sizeof(*a->tail) + alloc_size); a->tail->next = (Arena_Region*)ARENA_MALLOC(sizeof(*a->tail) + alloc_size);
if (a->tail->next == NULL) { if (a->tail->next == NULL) {
ARENA_ASSERT(false && "Reallocation failed"); ARENA_ASSERT(false && "Allocation failed");
return NULL; return NULL;
} }
@@ -291,6 +306,10 @@ void *arena_copy(Arena *a, const void *src, size_t size)
} }
void *copy = arena_alloc(a, size); void *copy = arena_alloc(a, size);
if (copy == NULL) {
return NULL;
}
memcpy(copy, src, size); memcpy(copy, src, size);
return copy; return copy;
@@ -306,19 +325,6 @@ char *arena_strdup(Arena *a, const char *s)
return (char*)arena_copy(a, s, strlen(s) + 1); return (char*)arena_copy(a, s, strlen(s) + 1);
} }
void arena_reset(Arena *a)
{
if (a == NULL) {
return;
}
for (Arena_Region *cur = a->head; cur != NULL; cur = cur->next) {
cur->count = 0;
}
a->tail = a->head;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif // __cplusplus #endif // __cplusplus
@@ -328,6 +334,7 @@ void arena_reset(Arena *a)
/* /*
* Revision history: * Revision history:
* *
* 1.1.2 (2026-01-10) Minor changes; check result of alloc in arena_copy()
* 1.1.1 (2025-11-18) Implement memory alignment; improve docs * 1.1.1 (2025-11-18) Implement memory alignment; improve docs
* 1.1.0 (2025-11-18) New helper functions: arena_copy(), arena_strdup() * 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.3 (2025-09-10) Renamed parameter bytes to size in arena_alloc()

2
test.c
View File

@@ -25,6 +25,8 @@ void arena_print(Arena arena)
int main(void) int main(void)
{ {
printf("Alignment: %zu\n", ARENA_ALIGNMENT);
Arena a = {0}; Arena a = {0};
arena_alloc(&a, 4012); arena_alloc(&a, 4012);