diff --git a/CMakeLists.txt b/CMakeLists.txt index b3644d2..c1fa076 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,9 @@ project(dynarr LANGUAGES C ) +add_compile_options(-fsanitize=address) +add_link_options(-fsanitize=address) + set(CMAKE_C_STANDARD 17) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/src/dyn_arr.c b/src/dyn_arr.c index 187ab9d..38e2584 100644 --- a/src/dyn_arr.c +++ b/src/dyn_arr.c @@ -1,5 +1,6 @@ // Special thanks to https://bytesbeneath.com/p/dynamic-arrays-in-c #include "dyn_arr.h" +#include #include #include #include @@ -10,8 +11,11 @@ void *dyn_arr_init(size_t item_size, size_t capacity) { void *dyna_ptr = NULL; size_t size = item_size * capacity + sizeof(dyna_header); dyna_header *header = malloc(size); + printf("Pointer init: %p %p\n", header, header + 1); + printf("Pointer pop: %p %zu\n", header, item_size); if (header) { + header->item_size = item_size; header->capacity = capacity; header->length = 0; dyna_ptr = header + 1; @@ -20,11 +24,15 @@ void *dyn_arr_init(size_t item_size, size_t capacity) { return dyna_ptr; } -void *dyna_ensure_capacity(void *array, size_t item_count, size_t item_size) { +void *dyna_ensure_capacity(void *array, int64_t item_count) { + size_t item_size = dyna_item_size(array); dyna_header *header = dyna_get_header(array); size_t minimum_capacity = header->length + item_count; + size_t maximum_capacity = + header->length + item_count * ARRAY_GROWTH_MULTIPLIER; - if (header->capacity > minimum_capacity) { + if (header->capacity > minimum_capacity && + header->capacity < maximum_capacity) { return header + 1; } @@ -35,6 +43,7 @@ void *dyna_ensure_capacity(void *array, size_t item_count, size_t item_size) { size_t new_size = sizeof(dyna_header) + new_capacity * item_size; header = realloc(header, new_size); + printf("Pointer capacity: %p %p\n", header, header + 1); header->capacity = new_capacity; return header + 1; } @@ -55,13 +64,18 @@ void dyn_arr_pop(void *array, size_t item_size) { size_t new_capacity = dyna_length(array) * ARRAY_GROWTH_MULTIPLIER; dyna_capacity(array) = new_capacity; - size_t new_size = sizeof(dyna_header) + new_capacity * item_size; - dyna_header *header = dyna_get_header(array); + size_t new_size = sizeof(dyna_header) + (new_capacity * item_size); + + dyna_header *header; header = realloc(dyna_get_header(array), new_size); + array = header + 1; + printf("Pointer pop: %p %p %zu\n", header, array, item_size); } void dyna_deinit(void *array) { + printf("Pointer deinit: %p\n", array); free(dyna_get_header(array)); + array = NULL; } bool dyna_empty(void *array) { diff --git a/src/dyn_arr.h b/src/dyn_arr.h index cebddef..180974c 100644 --- a/src/dyn_arr.h +++ b/src/dyn_arr.h @@ -21,6 +21,7 @@ */ typedef struct dyna_header { + size_t item_size; size_t capacity; size_t length; } dyna_header; @@ -31,19 +32,23 @@ void *dyn_arr_init(size_t item_size, size_t capacity); // Modification #define dyna_append(array, value) \ - ((array) = dyna_ensure_capacity(array, 1, sizeof(value)), \ + ((array) = dyna_ensure_capacity(array, 1), \ (array)[dyna_get_header(array)->length] = (value), \ &(array)[dyna_get_header(array)->length++]) -void *dyna_ensure_capacity(void *array, size_t item_count, size_t item_size); +void *dyna_ensure_capacity(void *array, int64_t item_count); + +#define dyna_pop(array) \ + ((array) = dyna_ensure_capacity(array, -1), \ + &(array)[dyna_get_header(array)->length--]) -#define dyna_pop(array) dyn_arr_pop(array, sizeof(typeof(*array))) void dyn_arr_pop(void *array, size_t item_size); void dyna_deinit(void *array); // Get meta data -#define dyna_get_header(array) ((dyna_header *)(array)-1) +#define dyna_get_header(array) ((dyna_header *)(array) - 1) +#define dyna_item_size(array) (dyna_get_header(array)->item_size) #define dyna_length(array) (dyna_get_header(array)->length) #define dyna_capacity(array) (dyna_get_header(array)->capacity) bool dyna_empty(void *array); diff --git a/src/main.c b/src/main.c index 9b24bce..4e92e37 100644 --- a/src/main.c +++ b/src/main.c @@ -6,17 +6,19 @@ int main() { uint64_t *dyna_array = dyna_init(uint64_t); - for (uint64_t i = 0; i < 9999999; i++) { + for (uint64_t i = 0; i < 9; i++) { dyna_append(dyna_array, i); printf("length: %zu capacity: %zu\n", dyna_array[i], dyna_capacity(dyna_array)); } - for (uint64_t i = 9999999; i > 0; i--) { + for (uint64_t i = 9; i > 0; i--) { printf("length: %zu capacity: %zu\n", dyna_array[i], dyna_capacity(dyna_array)); dyna_pop(dyna_array); } + dyna_deinit(dyna_array); + return EXIT_SUCCESS; }