feat: add null checks to dynamic array macros for improved safety
This commit is contained in:
@@ -23,51 +23,75 @@ typedef struct {
|
|||||||
} ArrayHeader;
|
} ArrayHeader;
|
||||||
|
|
||||||
|
|
||||||
#define array_create(arr) \
|
#define array_create(arr) \
|
||||||
do { \
|
do { \
|
||||||
ArrayHeader *header = malloc(sizeof(*arr) * DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE + sizeof(ArrayHeader)); \
|
ArrayHeader *header = malloc( \
|
||||||
header->size = 0; \
|
sizeof(*(arr)) * DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE + sizeof(ArrayHeader) \
|
||||||
header->capacity = DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE; \
|
); \
|
||||||
\
|
if (header == NULL) { \
|
||||||
arr = (void *)(header + 1); \
|
abort(); \
|
||||||
|
} \
|
||||||
|
header->size = 0; \
|
||||||
|
header->capacity = DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE; \
|
||||||
|
\
|
||||||
|
(arr) = (void *)(header + 1); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
#define array_get_header(arr) ((ArrayHeader*)(arr) - 1)
|
#define array_get_header(arr) \
|
||||||
|
((arr) ? ((ArrayHeader*)(arr) - 1) : NULL)
|
||||||
|
|
||||||
|
|
||||||
#define array_destroy(arr) \
|
#define array_destroy(arr) \
|
||||||
do { \
|
do { \
|
||||||
free(array_get_header(arr)); \
|
if ((arr) == NULL) { \
|
||||||
arr = NULL; \
|
break; \
|
||||||
|
} \
|
||||||
|
free(array_get_header(arr)); \
|
||||||
|
(arr) = NULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
#define array_push_value(arr, value) \
|
#define array_push_value(arr, value) \
|
||||||
do { \
|
do { \
|
||||||
ArrayHeader *header = array_get_header(arr); \
|
if ((arr) == NULL) { \
|
||||||
if (header->size + 1 > header->capacity) { \
|
array_create(arr); \
|
||||||
size_t new_capacity = header->capacity * DYNAMIC_ARRAY_CAPACITY_FACTOR; \
|
} \
|
||||||
ArrayHeader *new_header = realloc(header, sizeof(*arr) * new_capacity + sizeof(ArrayHeader)); \
|
ArrayHeader *header = array_get_header(arr); \
|
||||||
if (new_header != NULL) { \
|
if (header->size >= header->capacity) { \
|
||||||
header = new_header; \
|
size_t new_capacity = header->capacity * DYNAMIC_ARRAY_CAPACITY_FACTOR; \
|
||||||
} \
|
ArrayHeader *new_header = realloc( \
|
||||||
header->capacity = new_capacity; \
|
header, sizeof(*(arr)) * new_capacity + sizeof(ArrayHeader) \
|
||||||
arr = (void *)(header + 1); \
|
); \
|
||||||
} \
|
if (new_header == NULL) { \
|
||||||
arr[header->size] = value; \
|
abort(); \
|
||||||
header->size++; \
|
} \
|
||||||
|
header = new_header; \
|
||||||
|
header->capacity = new_capacity; \
|
||||||
|
(arr) = (void *)(header + 1); \
|
||||||
|
} \
|
||||||
|
(arr)[header->size] = (value); \
|
||||||
|
header->size++; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
#define array_pop(arr) \
|
#define array_pop(arr) \
|
||||||
do { \
|
do { \
|
||||||
ArrayHeader *header = array_get_header(arr); \
|
if ((arr) == NULL) { \
|
||||||
if (header->size == 0) { \
|
break; \
|
||||||
break; \
|
} \
|
||||||
} \
|
ArrayHeader *header = array_get_header(arr); \
|
||||||
header->size--; \
|
if (header->size == 0) { \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
header->size--; \
|
||||||
} while (0)
|
} 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
|
#endif
|
||||||
Reference in New Issue
Block a user