refactor dynamic array: enhance element size handling, update memory management, and improve API functions

This commit is contained in:
2026-03-27 09:56:36 -03:00
parent e86a0af333
commit eb1bd7837e
4 changed files with 82 additions and 61 deletions

3
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[submodule "submodules/external/unity_cmake/Unity"]
path = submodules/external/unity_cmake/Unity
url = https://github.com/ThrowTheSwitch/Unity.git
[submodule "submodules/external/unity"]
path = submodules/external/unity
url = https://github.com/ThrowTheSwitch/Unity.git

View File

@@ -7,10 +7,12 @@
Array *array_create(const ArrayCreateOptions *options) {
const ArrayCreateOptions opt = options != NULL ? *options : DEFAULT_ARRAY_CREATE_OPTIONS;
Array *array = (Array*) malloc(sizeof(Array));
Array *array = malloc(sizeof(Array));
array->capacity = opt.initial_size;
array->value = (int*) calloc(array->capacity, sizeof(int));
array->value = calloc(array->capacity, opt.element_size);
array->size = 0;
array->element_size = opt.element_size;
return array;
}
@@ -24,27 +26,27 @@ void array_deconstructor(Array **pp_array) {
}
void array_resize(Array *p_array, const int new_size) {
int *new_ptr = realloc(p_array->value, new_size*sizeof(int));
int *new_ptr = realloc(p_array->value, new_size*p_array->element_size);
if (new_ptr == NULL) {
exit(1);
}
if (new_size > p_array->capacity) {
memset(new_ptr + p_array->capacity, 0, (new_size - p_array->capacity) * sizeof(int));
memset(new_ptr + p_array->capacity, 0, (new_size - p_array->capacity) * p_array->element_size);
}
p_array->value = new_ptr;
p_array->capacity = new_size;
}
int *array_get_value(const Array *array, const int index) {
if (index > array->capacity) {
void *array_get_value(const Array *p_array, const int index) {
if (index > p_array->capacity) {
return NULL;
}
return &array->value[index];
return p_array->value + index * p_array->element_size;
}
void array_set_value(Array *p_array, const int index, const int value) {
void array_set_value(Array *p_array, const int index, const void *value) {
if (index > p_array->capacity) {
int new_size = p_array->capacity;
while (index >= new_size) {
@@ -52,10 +54,12 @@ void array_set_value(Array *p_array, const int index, const int value) {
}
array_resize(p_array, new_size);
}
memcpy(
array_get_value(p_array, index), value, p_array->element_size
);
if (index >= p_array->size) {
p_array->size = index + 1;
}
p_array->value[index] = value;
}
int array_get_size(const Array *p_array) {

View File

@@ -4,7 +4,9 @@
typedef struct Array {
int *value;
void *value;
size_t element_size;
int size;
int capacity;
} Array;
@@ -12,11 +14,12 @@ typedef struct Array {
typedef struct ArrayCreateOptions {
int initial_size;
size_t element_size;
} ArrayCreateOptions;
#define DEFAULT_ARRAY_CREATE_OPTIONS \
(ArrayCreateOptions){ DEFAULT_ARRAY_SIZE }
(ArrayCreateOptions){ DEFAULT_ARRAY_SIZE, sizeof(int) }
Array *array_create(const ArrayCreateOptions *options);
@@ -27,10 +30,10 @@ void array_deconstructor(Array **pp_array);
void array_resize(Array *p_array, int new_size);
int *array_get_value(const Array *p_array, int index);
void *array_get_value(const Array *p_array, int index);
void array_set_value(Array *p_array, int index, int value);
void array_set_value(Array *p_array, int index, const void *value);
int array_get_size(const Array *p_array);

View File

@@ -48,7 +48,7 @@ void test_array_resize_expand(void) {
void test_array_resize_shrink(void) {
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 50});
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 50, .element_size = sizeof(int)});
const int NEW_CAPACITY = 20;
array_resize(array, NEW_CAPACITY);
@@ -60,45 +60,49 @@ void test_array_resize_shrink(void) {
void test_array_set_value_within_capacity(void) {
Array *array = array_create(NULL);
Array *p_array = array_create(NULL);
const int INDEX = 5;
const int VALUE = 42;
const int EXPECTED_VALUE = 42;
array_set_value(array, INDEX, VALUE);
array_set_value(p_array, INDEX, &EXPECTED_VALUE);
TEST_ASSERT_EQUAL(VALUE, array->value[INDEX]);
const int VALUE = *(int*)array_get_value(p_array, INDEX);
array_deconstructor(&array);
TEST_ASSERT_EQUAL(EXPECTED_VALUE, VALUE);
array_deconstructor(&p_array);
}
void test_array_set_value_beyond_capacity(void) {
Array *array = array_create(NULL);
Array *p_array = array_create(NULL);
const int INDEX = 50;
const int VALUE = 99;
const int ORIGINAL_CAPACITY = array->capacity;
const int EXPECTED_VALUE = 99;
const int ORIGINAL_CAPACITY = p_array->capacity;
array_set_value(array, INDEX, VALUE);
array_set_value(p_array, INDEX, &EXPECTED_VALUE);
TEST_ASSERT_GREATER_THAN(ORIGINAL_CAPACITY, array->capacity);
TEST_ASSERT_EQUAL(VALUE, array->value[INDEX]);
const int VALUE = *(int*)array_get_value(p_array, INDEX);
array_deconstructor(&array);
TEST_ASSERT_GREATER_THAN(ORIGINAL_CAPACITY, p_array->capacity);
TEST_ASSERT_EQUAL(EXPECTED_VALUE, VALUE);
array_deconstructor(&p_array);
}
void test_array_get_value_valid_index(void) {
Array *array = array_create(NULL);
Array *p_array = array_create(NULL);
const int INDEX = 3;
const int VALUE = 77;
const int EXPECTED_VALUE = 77;
array->value[INDEX] = VALUE;
int *result = array_get_value(array, INDEX);
array_set_value(p_array, INDEX, &EXPECTED_VALUE);
const int *result = array_get_value(p_array, INDEX);
TEST_ASSERT_NOT_NULL(result);
TEST_ASSERT_EQUAL(VALUE, *result);
TEST_ASSERT_EQUAL(EXPECTED_VALUE, *result);
array_deconstructor(&array);
array_deconstructor(&p_array);
}
@@ -106,8 +110,8 @@ void test_array_get_value_zero_index(void) {
Array *array = array_create(NULL);
const int VALUE = 100;
array->value[0] = VALUE;
int *result = array_get_value(array, 0);
array_set_value(array, 0, &VALUE);
const int *result = array_get_value(array, 0);
TEST_ASSERT_NOT_NULL(result);
TEST_ASSERT_EQUAL(VALUE, *result);
@@ -119,7 +123,7 @@ void test_array_get_value_zero_index(void) {
void test_array_get_value_beyond_capacity(void) {
Array *array = array_create(NULL);
int *result = array_get_value(array, array->capacity + 1);
const int *result = array_get_value(array, array->capacity + 1);
TEST_ASSERT_NULL(result);
@@ -128,18 +132,21 @@ void test_array_get_value_beyond_capacity(void) {
void test_array_multiple_operations(void) {
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 5});
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 5, .element_size = sizeof(int)});
array_set_value(array, 0, 10);
array_set_value(array, 1, 20);
array_set_value(array, 2, 30);
const int VALUE = 42;
TEST_ASSERT_EQUAL(10, *array_get_value(array, 0));
TEST_ASSERT_EQUAL(20, *array_get_value(array, 1));
TEST_ASSERT_EQUAL(30, *array_get_value(array, 2));
array_set_value(array, 0, &VALUE);
TEST_ASSERT_EQUAL(VALUE, *(int *)array_get_value(array, 0));
array_set_value(array, 10, 100);
TEST_ASSERT_EQUAL(100, *array_get_value(array, 10));
array_set_value(array, 1, &VALUE);
TEST_ASSERT_EQUAL(VALUE, *(int *)array_get_value(array, 1));
array_set_value(array, 2, &VALUE);
TEST_ASSERT_EQUAL(VALUE, *(int *)array_get_value(array, 2));
array_set_value(array, 10, &VALUE);
TEST_ASSERT_EQUAL(VALUE, *(int *)array_get_value(array, 10));
array_deconstructor(&array);
}
@@ -197,7 +204,9 @@ void test_array_get_size_initial(void) {
void test_array_get_size_after_single_set(void) {
Array *array = array_create(NULL);
array_set_value(array, 0, 42);
const int VALUE = 42;
array_set_value(array, 0, &VALUE);
int size = array_get_size(array);
TEST_ASSERT_EQUAL(1, size);
@@ -209,9 +218,11 @@ void test_array_get_size_after_single_set(void) {
void test_array_get_size_after_multiple_sets(void) {
Array *array = array_create(NULL);
array_set_value(array, 0, 10);
array_set_value(array, 1, 20);
array_set_value(array, 2, 30);
const int VALUE = 42;
array_set_value(array, 0, &VALUE);
array_set_value(array, 1, &VALUE);
array_set_value(array, 2, &VALUE);
int size = array_get_size(array);
TEST_ASSERT_EQUAL(3, size);
@@ -223,8 +234,10 @@ void test_array_get_size_after_multiple_sets(void) {
void test_array_get_size_with_gap_in_indices(void) {
Array *array = array_create(NULL);
array_set_value(array, 0, 10);
array_set_value(array, 5, 50);
const int VALUE = 42;
array_set_value(array, 0, &VALUE);
array_set_value(array, 5, &VALUE);
int size = array_get_size(array);
TEST_ASSERT_EQUAL(6, size);
@@ -236,9 +249,11 @@ void test_array_get_size_with_gap_in_indices(void) {
void test_array_get_size_capacity_relationship(void) {
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 10});
array_set_value(array, 0, 1);
array_set_value(array, 1, 2);
array_set_value(array, 2, 3);
const int VALUE = 42;
array_set_value(array, 0, &VALUE);
array_set_value(array, 1, &VALUE);
array_set_value(array, 2, &VALUE);
int size = array_get_size(array);
int capacity = array_get_capacity(array);
@@ -252,12 +267,14 @@ void test_array_get_size_capacity_relationship(void) {
void test_array_get_size_after_resize_beyond_capacity(void) {
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 5});
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 5, .element_size = sizeof(int)});
array_set_value(array, 0, 10);
array_set_value(array, 15, 100);
int size = array_get_size(array);
int capacity = array_get_capacity(array);
const int VALUE = 42;
array_set_value(array, 0, &VALUE);
array_set_value(array, 15, &VALUE);
const int size = array_get_size(array);
const int capacity = array_get_capacity(array);
TEST_ASSERT_EQUAL(16, size);
TEST_ASSERT_LESS_OR_EQUAL(capacity, size);