test: Added test for init and destroy
Also changed a few things like destroy tanking a double pointer so that is more secure and making sure before hand that capacity is not that ridiculous of a size, still, shit can get pass but generally is fine
This commit is contained in:
@@ -26,6 +26,10 @@ ArrayList *arraylist_init(size_t capacity, size_t elem_size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (capacity > SIZE_MAX / elem_size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ArrayList *arr = malloc(sizeof(ArrayList));
|
||||
if (arr == NULL) {
|
||||
return NULL;
|
||||
@@ -42,17 +46,16 @@ ArrayList *arraylist_init(size_t capacity, size_t elem_size) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
ArrayListErr arraylist_destroy(ArrayList *arr) {
|
||||
if (arr == NULL) {
|
||||
ArrayListErr arraylist_destroy(ArrayList **arr) {
|
||||
if (arr == NULL || *arr == NULL) {
|
||||
return ARRLIST_NULL_ARG;
|
||||
}
|
||||
|
||||
arr->capacity = 0;
|
||||
arr->elem_size = 0;
|
||||
arr->len = 0;
|
||||
free(arr->buffer);
|
||||
arr->buffer = NULL;
|
||||
free(arr);
|
||||
// No problem on using free on NULL :)
|
||||
free((*arr)->buffer);
|
||||
free(*arr);
|
||||
*arr = NULL;
|
||||
|
||||
return ARRLIST_OK;
|
||||
}
|
||||
|
||||
@@ -94,10 +97,16 @@ static ArrayListErr arraylist_grow(ArrayList *arr) {
|
||||
// and only used by funtions that already verified
|
||||
// arr is not null, same with shrink.
|
||||
size_t new_capacity = arr->capacity * 2;
|
||||
|
||||
if (new_capacity > SIZE_MAX / arr->elem_size) {
|
||||
return ARRLIST_ALLOC_OVERFLOW;
|
||||
}
|
||||
|
||||
void *tmp = realloc(arr->buffer, new_capacity * arr->elem_size);
|
||||
if (tmp == NULL) {
|
||||
return ARRLIST_BAD_ALLOC;
|
||||
}
|
||||
|
||||
arr->capacity = new_capacity;
|
||||
arr->buffer = tmp;
|
||||
return ARRLIST_OK;
|
||||
@@ -105,10 +114,16 @@ static ArrayListErr arraylist_grow(ArrayList *arr) {
|
||||
|
||||
static ArrayListErr arraylist_shrink(ArrayList *arr) {
|
||||
size_t new_capacity = arr->capacity / 2;
|
||||
|
||||
if (new_capacity > SIZE_MAX / arr->elem_size) {
|
||||
return ARRLIST_ALLOC_OVERFLOW;
|
||||
}
|
||||
|
||||
void *tmp = realloc(arr->buffer, new_capacity *arr->elem_size);
|
||||
if (tmp == NULL) {
|
||||
return ARRLIST_BAD_ALLOC;
|
||||
}
|
||||
|
||||
arr->capacity = new_capacity;
|
||||
arr->buffer = tmp;
|
||||
return ARRLIST_OK;
|
||||
@@ -146,14 +161,17 @@ ArrayListErr arraylist_push_front(ArrayList *arr, void *data) {
|
||||
}
|
||||
|
||||
// No problem if array is full because it grows if it's full
|
||||
for (size_t i = arr->len - 1; i >= 0; i--) {
|
||||
memcpy(
|
||||
arr->buffer + ((i + 1) * arr->elem_size),
|
||||
arr->buffer + (i * arr->elem_size),
|
||||
arr->elem_size);
|
||||
}
|
||||
memmove(
|
||||
arr->buffer,
|
||||
arr->buffer + arr->elem_size,
|
||||
(arr->len - 1) * arr->elem_size
|
||||
);
|
||||
|
||||
memcpy(
|
||||
arr->buffer,
|
||||
data,
|
||||
arr->elem_size);
|
||||
|
||||
memcpy(arr->buffer, data, arr->elem_size);
|
||||
arr->len++;
|
||||
|
||||
return ARRLIST_OK;
|
||||
@@ -164,7 +182,7 @@ ArrayListErr arraylist_insert(ArrayList *arr, size_t index, void *data) {
|
||||
return ARRLIST_NULL_ARG;
|
||||
}
|
||||
|
||||
if (index >= arr->len) {
|
||||
if (index > arr->len) {
|
||||
return ARRLIST_OUT_OF_BOUNDS;
|
||||
}
|
||||
|
||||
@@ -175,14 +193,15 @@ ArrayListErr arraylist_insert(ArrayList *arr, size_t index, void *data) {
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = arr->len - 1; i >= index; i--) {
|
||||
memcpy(
|
||||
arr->buffer + ((i + 1) * arr->elem_size),
|
||||
arr->buffer + (i * arr->elem_size),
|
||||
arr->elem_size);
|
||||
}
|
||||
memmove(
|
||||
arr->buffer + ((index + 1) * arr->elem_size),
|
||||
arr->buffer + (index * arr->elem_size),
|
||||
(arr->len - index) * arr->elem_size);
|
||||
|
||||
memcpy(arr->buffer + (index * arr->elem_size),
|
||||
data,
|
||||
arr->elem_size);
|
||||
|
||||
memcpy(arr->buffer + (index * arr->elem_size), data, arr->elem_size);
|
||||
arr->len++;
|
||||
|
||||
return ARRLIST_OK;
|
||||
@@ -240,12 +259,10 @@ ArrayListErr arraylist_pop_front(ArrayList *arr, void *out) {
|
||||
);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < arr->len; i++) {
|
||||
memcpy(
|
||||
arr->buffer + (i * arr->elem_size),
|
||||
arr->buffer + ((i + 1) * arr->elem_size),
|
||||
arr->elem_size);
|
||||
}
|
||||
memmove(
|
||||
arr->buffer + arr->elem_size,
|
||||
arr->buffer,
|
||||
(arr->len - 1) * arr->elem_size);
|
||||
|
||||
arr->len--;
|
||||
|
||||
@@ -329,6 +346,10 @@ ArrayListErr arraylist_resize(ArrayList *arr, size_t new_capacity) {
|
||||
return ARRLIST_INVALID_CAPACITY;
|
||||
}
|
||||
|
||||
if (new_capacity > SIZE_MAX / arr->elem_size) {
|
||||
return ARRLIST_ALLOC_OVERFLOW;
|
||||
}
|
||||
|
||||
uint8_t *tmp = realloc(arr->buffer, new_capacity * arr->elem_size);
|
||||
if (tmp == NULL) {
|
||||
return ARRLIST_BAD_ALLOC;
|
||||
@@ -348,6 +369,10 @@ ArrayListErr arraylist_reserve(ArrayList *arr, size_t size_to_reserve) {
|
||||
return ARRLIST_INVALID_CAPACITY;
|
||||
}
|
||||
|
||||
if (arr->capacity + size_to_reserve > SIZE_MAX / arr->elem_size) {
|
||||
return ARRLIST_ALLOC_OVERFLOW;
|
||||
}
|
||||
|
||||
uint8_t *tmp = realloc(
|
||||
arr->buffer,
|
||||
(arr->capacity + size_to_reserve) * arr->elem_size);
|
||||
|
||||
Reference in New Issue
Block a user