refactor dynamic array: enhance element size handling, update memory management, and improve API functions
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user