From 09e1a360fd441ff20439366de174a31b8e77bf00 Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Wed, 15 Apr 2026 20:59:52 -0300 Subject: [PATCH] feat: add null checks to dynamic array macros for improved safety --- src/dynamic_array.h | 90 ++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 33 deletions(-) diff --git a/src/dynamic_array.h b/src/dynamic_array.h index 764b328..a2a937e 100644 --- a/src/dynamic_array.h +++ b/src/dynamic_array.h @@ -23,51 +23,75 @@ typedef struct { } ArrayHeader; -#define array_create(arr) \ - do { \ - ArrayHeader *header = malloc(sizeof(*arr) * DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE + sizeof(ArrayHeader)); \ - header->size = 0; \ - header->capacity = DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE; \ - \ - arr = (void *)(header + 1); \ +#define array_create(arr) \ + do { \ + ArrayHeader *header = malloc( \ + sizeof(*(arr)) * DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE + sizeof(ArrayHeader) \ + ); \ + if (header == NULL) { \ + abort(); \ + } \ + header->size = 0; \ + header->capacity = DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE; \ + \ + (arr) = (void *)(header + 1); \ } while(0) -#define array_get_header(arr) ((ArrayHeader*)(arr) - 1) +#define array_get_header(arr) \ + ((arr) ? ((ArrayHeader*)(arr) - 1) : NULL) -#define array_destroy(arr) \ - do { \ - free(array_get_header(arr)); \ - arr = NULL; \ +#define array_destroy(arr) \ + do { \ + if ((arr) == NULL) { \ + break; \ + } \ + free(array_get_header(arr)); \ + (arr) = NULL; \ } while (0) -#define array_push_value(arr, value) \ - do { \ - ArrayHeader *header = array_get_header(arr); \ - if (header->size + 1 > header->capacity) { \ - size_t new_capacity = header->capacity * DYNAMIC_ARRAY_CAPACITY_FACTOR; \ - ArrayHeader *new_header = realloc(header, sizeof(*arr) * new_capacity + sizeof(ArrayHeader)); \ - if (new_header != NULL) { \ - header = new_header; \ - } \ - header->capacity = new_capacity; \ - arr = (void *)(header + 1); \ - } \ - arr[header->size] = value; \ - header->size++; \ +#define array_push_value(arr, value) \ + do { \ + if ((arr) == NULL) { \ + array_create(arr); \ + } \ + ArrayHeader *header = array_get_header(arr); \ + if (header->size >= header->capacity) { \ + size_t new_capacity = header->capacity * DYNAMIC_ARRAY_CAPACITY_FACTOR; \ + ArrayHeader *new_header = realloc( \ + header, sizeof(*(arr)) * new_capacity + sizeof(ArrayHeader) \ + ); \ + if (new_header == NULL) { \ + abort(); \ + } \ + header = new_header; \ + header->capacity = new_capacity; \ + (arr) = (void *)(header + 1); \ + } \ + (arr)[header->size] = (value); \ + header->size++; \ } while (0) -#define array_pop(arr) \ - do { \ - ArrayHeader *header = array_get_header(arr); \ - if (header->size == 0) { \ - break; \ - } \ - header->size--; \ +#define array_pop(arr) \ + do { \ + if ((arr) == NULL) { \ + break; \ + } \ + ArrayHeader *header = array_get_header(arr); \ + if (header->size == 0) { \ + break; \ + } \ + header->size--; \ } while (0) +#define array_size(arr) \ + ((arr) ? array_get_header(arr)->size : 0) + +#define array_capacity(arr) \ + ((arr) ? array_get_header(arr)->capacity : 0) + #endif \ No newline at end of file