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"] [submodule "submodules/external/unity"]
path = submodules/external/unity path = submodules/external/unity
url = https://github.com/ThrowTheSwitch/Unity.git url = https://github.com/ThrowTheSwitch/Unity.git

View File

@@ -7,10 +7,12 @@
Array *array_create(const ArrayCreateOptions *options) { Array *array_create(const ArrayCreateOptions *options) {
const ArrayCreateOptions opt = options != NULL ? *options : DEFAULT_ARRAY_CREATE_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->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; return array;
} }
@@ -24,27 +26,27 @@ void array_deconstructor(Array **pp_array) {
} }
void array_resize(Array *p_array, const int new_size) { 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) { if (new_ptr == NULL) {
exit(1); exit(1);
} }
if (new_size > p_array->capacity) { 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->value = new_ptr;
p_array->capacity = new_size; p_array->capacity = new_size;
} }
int *array_get_value(const Array *array, const int index) { void *array_get_value(const Array *p_array, const int index) {
if (index > array->capacity) { if (index > p_array->capacity) {
return NULL; 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) { if (index > p_array->capacity) {
int new_size = p_array->capacity; int new_size = p_array->capacity;
while (index >= new_size) { 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); array_resize(p_array, new_size);
} }
memcpy(
array_get_value(p_array, index), value, p_array->element_size
);
if (index >= p_array->size) { if (index >= p_array->size) {
p_array->size = index + 1; p_array->size = index + 1;
} }
p_array->value[index] = value;
} }
int array_get_size(const Array *p_array) { int array_get_size(const Array *p_array) {

View File

@@ -4,7 +4,9 @@
typedef struct Array { typedef struct Array {
int *value; void *value;
size_t element_size;
int size; int size;
int capacity; int capacity;
} Array; } Array;
@@ -12,11 +14,12 @@ typedef struct Array {
typedef struct ArrayCreateOptions { typedef struct ArrayCreateOptions {
int initial_size; int initial_size;
size_t element_size;
} ArrayCreateOptions; } ArrayCreateOptions;
#define DEFAULT_ARRAY_CREATE_OPTIONS \ #define DEFAULT_ARRAY_CREATE_OPTIONS \
(ArrayCreateOptions){ DEFAULT_ARRAY_SIZE } (ArrayCreateOptions){ DEFAULT_ARRAY_SIZE, sizeof(int) }
Array *array_create(const ArrayCreateOptions *options); 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); 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); 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) { 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; const int NEW_CAPACITY = 20;
array_resize(array, NEW_CAPACITY); array_resize(array, NEW_CAPACITY);
@@ -60,45 +60,49 @@ void test_array_resize_shrink(void) {
void test_array_set_value_within_capacity(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 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) { 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 INDEX = 50;
const int VALUE = 99; const int EXPECTED_VALUE = 99;
const int ORIGINAL_CAPACITY = array->capacity; 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); const int VALUE = *(int*)array_get_value(p_array, INDEX);
TEST_ASSERT_EQUAL(VALUE, array->value[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) { 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 INDEX = 3;
const int VALUE = 77; const int EXPECTED_VALUE = 77;
array->value[INDEX] = VALUE; array_set_value(p_array, INDEX, &EXPECTED_VALUE);
int *result = array_get_value(array, INDEX); const int *result = array_get_value(p_array, INDEX);
TEST_ASSERT_NOT_NULL(result); 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); Array *array = array_create(NULL);
const int VALUE = 100; const int VALUE = 100;
array->value[0] = VALUE; array_set_value(array, 0, &VALUE);
int *result = array_get_value(array, 0); const int *result = array_get_value(array, 0);
TEST_ASSERT_NOT_NULL(result); TEST_ASSERT_NOT_NULL(result);
TEST_ASSERT_EQUAL(VALUE, *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) { void test_array_get_value_beyond_capacity(void) {
Array *array = array_create(NULL); 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); TEST_ASSERT_NULL(result);
@@ -128,18 +132,21 @@ void test_array_get_value_beyond_capacity(void) {
void test_array_multiple_operations(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); const int VALUE = 42;
array_set_value(array, 1, 20);
array_set_value(array, 2, 30);
TEST_ASSERT_EQUAL(10, *array_get_value(array, 0)); array_set_value(array, 0, &VALUE);
TEST_ASSERT_EQUAL(20, *array_get_value(array, 1)); TEST_ASSERT_EQUAL(VALUE, *(int *)array_get_value(array, 0));
TEST_ASSERT_EQUAL(30, *array_get_value(array, 2));
array_set_value(array, 10, 100); array_set_value(array, 1, &VALUE);
TEST_ASSERT_EQUAL(100, *array_get_value(array, 10)); 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); array_deconstructor(&array);
} }
@@ -197,7 +204,9 @@ void test_array_get_size_initial(void) {
void test_array_get_size_after_single_set(void) { void test_array_get_size_after_single_set(void) {
Array *array = array_create(NULL); 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); int size = array_get_size(array);
TEST_ASSERT_EQUAL(1, size); 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) { void test_array_get_size_after_multiple_sets(void) {
Array *array = array_create(NULL); Array *array = array_create(NULL);
array_set_value(array, 0, 10); const int VALUE = 42;
array_set_value(array, 1, 20);
array_set_value(array, 2, 30); 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 size = array_get_size(array);
TEST_ASSERT_EQUAL(3, size); 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) { void test_array_get_size_with_gap_in_indices(void) {
Array *array = array_create(NULL); Array *array = array_create(NULL);
array_set_value(array, 0, 10); const int VALUE = 42;
array_set_value(array, 5, 50);
array_set_value(array, 0, &VALUE);
array_set_value(array, 5, &VALUE);
int size = array_get_size(array); int size = array_get_size(array);
TEST_ASSERT_EQUAL(6, size); 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) { void test_array_get_size_capacity_relationship(void) {
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 10}); Array *array = array_create(&(ArrayCreateOptions){.initial_size = 10});
array_set_value(array, 0, 1); const int VALUE = 42;
array_set_value(array, 1, 2);
array_set_value(array, 2, 3); 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 size = array_get_size(array);
int capacity = array_get_capacity(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) { 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); const int VALUE = 42;
array_set_value(array, 15, 100);
int size = array_get_size(array); array_set_value(array, 0, &VALUE);
int capacity = array_get_capacity(array); 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_EQUAL(16, size);
TEST_ASSERT_LESS_OR_EQUAL(capacity, size); TEST_ASSERT_LESS_OR_EQUAL(capacity, size);