Compare commits

..

No commits in common. "1ff1d5a4dd1df089bf4a9343925248fea9b1c474" and "75c3af43df589f8a646d310525bb83e730c35489" have entirely different histories.

4 changed files with 30 additions and 28 deletions

View file

@ -6,9 +6,6 @@ project(dynarr
LANGUAGES C LANGUAGES C
) )
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)
set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

View file

@ -1,6 +1,5 @@
// Special thanks to https://bytesbeneath.com/p/dynamic-arrays-in-c // Special thanks to https://bytesbeneath.com/p/dynamic-arrays-in-c
#include "dyn_arr.h" #include "dyn_arr.h"
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -11,11 +10,8 @@ void *dyn_arr_init(size_t item_size, size_t capacity) {
void *dyna_ptr = NULL; void *dyna_ptr = NULL;
size_t size = item_size * capacity + sizeof(dyna_header); size_t size = item_size * capacity + sizeof(dyna_header);
dyna_header *header = malloc(size); 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) { if (header) {
header->item_size = item_size;
header->capacity = capacity; header->capacity = capacity;
header->length = 0; header->length = 0;
dyna_ptr = header + 1; dyna_ptr = header + 1;
@ -24,15 +20,11 @@ void *dyn_arr_init(size_t item_size, size_t capacity) {
return dyna_ptr; return dyna_ptr;
} }
void *dyna_ensure_capacity(void *array, int64_t item_count) { void *dyna_ensure_capacity(void *array, size_t item_count, size_t item_size) {
size_t item_size = dyna_item_size(array);
dyna_header *header = dyna_get_header(array); dyna_header *header = dyna_get_header(array);
size_t minimum_capacity = header->length + item_count; 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; return header + 1;
} }
@ -43,15 +35,33 @@ void *dyna_ensure_capacity(void *array, int64_t item_count) {
size_t new_size = sizeof(dyna_header) + new_capacity * item_size; size_t new_size = sizeof(dyna_header) + new_capacity * item_size;
header = realloc(header, new_size); header = realloc(header, new_size);
printf("Pointer capacity: %p %p\n", header, header + 1);
header->capacity = new_capacity; header->capacity = new_capacity;
return header + 1; return header + 1;
} }
void dyn_arr_pop(void *array, size_t item_size) {
if (dyna_empty(array)) {
return;
}
dyna_length(array)--;
// Shrink if smaller than growth factor, may break if growth factor is > 2
if (dyna_length(array) >
(2 - ARRAY_GROWTH_MULTIPLIER) * dyna_capacity(array)) {
return;
}
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);
header = realloc(dyna_get_header(array), new_size);
}
void dyna_deinit(void *array) { void dyna_deinit(void *array) {
printf("Pointer deinit: %p\n", array);
free(dyna_get_header(array)); free(dyna_get_header(array));
array = NULL;
} }
bool dyna_empty(void *array) { bool dyna_empty(void *array) {

View file

@ -21,7 +21,6 @@
*/ */
typedef struct dyna_header { typedef struct dyna_header {
size_t item_size;
size_t capacity; size_t capacity;
size_t length; size_t length;
} dyna_header; } dyna_header;
@ -32,21 +31,19 @@ void *dyn_arr_init(size_t item_size, size_t capacity);
// Modification // Modification
#define dyna_append(array, value) \ #define dyna_append(array, value) \
((array) = dyna_ensure_capacity(array, 1), \ ((array) = dyna_ensure_capacity(array, 1, sizeof(value)), \
(array)[dyna_get_header(array)->length] = (value), \ (array)[dyna_get_header(array)->length] = (value), \
&(array)[dyna_get_header(array)->length++]) &(array)[dyna_get_header(array)->length++])
void *dyna_ensure_capacity(void *array, int64_t item_count); void *dyna_ensure_capacity(void *array, size_t item_count, size_t item_size);
#define dyna_pop(array) \ #define dyna_pop(array) dyn_arr_pop(array, sizeof(typeof(*array)))
((array) = dyna_ensure_capacity(array, -1), \ void dyn_arr_pop(void *array, size_t item_size);
&(array)[dyna_get_header(array)->length--])
void dyna_deinit(void *array); void dyna_deinit(void *array);
// Get meta data // 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_length(array) (dyna_get_header(array)->length)
#define dyna_capacity(array) (dyna_get_header(array)->capacity) #define dyna_capacity(array) (dyna_get_header(array)->capacity)
bool dyna_empty(void *array); bool dyna_empty(void *array);

View file

@ -6,19 +6,17 @@
int main() { int main() {
uint64_t *dyna_array = dyna_init(uint64_t); uint64_t *dyna_array = dyna_init(uint64_t);
for (uint64_t i = 0; i < 9; i++) { for (uint64_t i = 0; i < 9999999; i++) {
dyna_append(dyna_array, i); dyna_append(dyna_array, i);
printf("length: %zu capacity: %zu\n", dyna_array[i], printf("length: %zu capacity: %zu\n", dyna_array[i],
dyna_capacity(dyna_array)); dyna_capacity(dyna_array));
} }
for (uint64_t i = 9; i > 0; i--) { for (uint64_t i = 9999999; i > 0; i--) {
printf("length: %zu capacity: %zu\n", dyna_array[i], printf("length: %zu capacity: %zu\n", dyna_array[i],
dyna_capacity(dyna_array)); dyna_capacity(dyna_array));
dyna_pop(dyna_array); dyna_pop(dyna_array);
} }
dyna_deinit(dyna_array);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }