refactor dynamic array: update C standard, improve memory management, and add size/capacity functions

This commit is contained in:
2026-03-26 17:36:39 -03:00
parent a45a74ddff
commit e86a0af333
4 changed files with 278 additions and 8 deletions

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 4.2)
project(dynamic_array LANGUAGES C)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD 11)
# Configures Testing Framework

View File

@@ -7,7 +7,7 @@
Array *array_create(const ArrayCreateOptions *options) {
const ArrayCreateOptions opt = options != NULL ? *options : DEFAULT_ARRAY_CREATE_OPTIONS;
const auto array = (Array*) malloc(sizeof(Array));
Array *array = (Array*) malloc(sizeof(Array));
array->capacity = opt.initial_size;
array->value = (int*) calloc(array->capacity, sizeof(int));
@@ -20,7 +20,7 @@ void array_deconstructor(Array **pp_array) {
free((*pp_array)->value);
free(*pp_array);
*pp_array = nullptr;
*pp_array = NULL;
}
void array_resize(Array *p_array, const int new_size) {
@@ -39,15 +39,29 @@ void array_resize(Array *p_array, const int new_size) {
int *array_get_value(const Array *array, const int index) {
if (index > array->capacity) {
return nullptr;
return NULL;
}
return &array->value[index];
}
void array_set_value(Array *p_array, const int index, const int value) {
if (index > p_array->capacity) {
const int new_size = (index - p_array->capacity) * 2 + p_array->capacity;
int new_size = p_array->capacity;
while (index >= new_size) {
new_size *= 2;
}
array_resize(p_array, new_size);
}
if (index >= p_array->size) {
p_array->size = index + 1;
}
p_array->value[index] = value;
}
int array_get_size(const Array *p_array) {
return p_array->size;
}
int array_get_capacity(const Array *p_array) {
return p_array->capacity;
}

View File

@@ -30,4 +30,10 @@ void array_resize(Array *p_array, int new_size);
int *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, int value);
int array_get_size(const Array *p_array);
int array_get_capacity(const Array *p_array);

View File

@@ -11,7 +11,7 @@ void tearDown() {
void test_array_create_without_options(void) {
Array *array = array_create(nullptr);
const Array *array = array_create(NULL);
TEST_ASSERT_EQUAL(DEFAULT_ARRAY_SIZE, array->capacity);
}
@@ -27,12 +27,245 @@ void test_array_create_with_options(void) {
void test_array_deconstruct(void) {
Array *array = array_create(nullptr);
Array *array = array_create(NULL);
array_deconstructor(&array);
TEST_ASSERT_NULL(array);
}
void test_array_resize_expand(void) {
Array *array = array_create(NULL);
const int ORIGINAL_CAPACITY = array->capacity;
const int NEW_CAPACITY = 30;
array_resize(array, NEW_CAPACITY);
TEST_ASSERT_EQUAL(NEW_CAPACITY, array->capacity);
TEST_ASSERT_GREATER_THAN(ORIGINAL_CAPACITY, array->capacity);
array_deconstructor(&array);
}
void test_array_resize_shrink(void) {
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 50});
const int NEW_CAPACITY = 20;
array_resize(array, NEW_CAPACITY);
TEST_ASSERT_EQUAL(NEW_CAPACITY, array->capacity);
array_deconstructor(&array);
}
void test_array_set_value_within_capacity(void) {
Array *array = array_create(NULL);
const int INDEX = 5;
const int VALUE = 42;
array_set_value(array, INDEX, VALUE);
TEST_ASSERT_EQUAL(VALUE, array->value[INDEX]);
array_deconstructor(&array);
}
void test_array_set_value_beyond_capacity(void) {
Array *array = array_create(NULL);
const int INDEX = 50;
const int VALUE = 99;
const int ORIGINAL_CAPACITY = array->capacity;
array_set_value(array, INDEX, VALUE);
TEST_ASSERT_GREATER_THAN(ORIGINAL_CAPACITY, array->capacity);
TEST_ASSERT_EQUAL(VALUE, array->value[INDEX]);
array_deconstructor(&array);
}
void test_array_get_value_valid_index(void) {
Array *array = array_create(NULL);
const int INDEX = 3;
const int VALUE = 77;
array->value[INDEX] = VALUE;
int *result = array_get_value(array, INDEX);
TEST_ASSERT_NOT_NULL(result);
TEST_ASSERT_EQUAL(VALUE, *result);
array_deconstructor(&array);
}
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);
TEST_ASSERT_NOT_NULL(result);
TEST_ASSERT_EQUAL(VALUE, *result);
array_deconstructor(&array);
}
void test_array_get_value_beyond_capacity(void) {
Array *array = array_create(NULL);
int *result = array_get_value(array, array->capacity + 1);
TEST_ASSERT_NULL(result);
array_deconstructor(&array);
}
void test_array_multiple_operations(void) {
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 5});
array_set_value(array, 0, 10);
array_set_value(array, 1, 20);
array_set_value(array, 2, 30);
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, 10, 100);
TEST_ASSERT_EQUAL(100, *array_get_value(array, 10));
array_deconstructor(&array);
}
void test_array_get_capacity_default(void) {
Array *array = array_create(NULL);
int capacity = array_get_capacity(array);
TEST_ASSERT_EQUAL(DEFAULT_ARRAY_SIZE, capacity);
array_deconstructor(&array);
}
void test_array_get_capacity_custom_size(void) {
const int EXPECTED_CAPACITY = 25;
Array *array = array_create(&(ArrayCreateOptions){.initial_size = EXPECTED_CAPACITY});
int capacity = array_get_capacity(array);
TEST_ASSERT_EQUAL(EXPECTED_CAPACITY, capacity);
array_deconstructor(&array);
}
void test_array_get_capacity_after_resize(void) {
Array *array = array_create(NULL);
const int ORIGINAL_CAPACITY = array_get_capacity(array);
const int NEW_CAPACITY = 50;
array_resize(array, NEW_CAPACITY);
int capacity = array_get_capacity(array);
TEST_ASSERT_EQUAL(NEW_CAPACITY, capacity);
TEST_ASSERT_NOT_EQUAL(ORIGINAL_CAPACITY, capacity);
array_deconstructor(&array);
}
void test_array_get_size_initial(void) {
Array *array = array_create(NULL);
int size = array_get_size(array);
TEST_ASSERT_EQUAL(0, size);
array_deconstructor(&array);
}
void test_array_get_size_after_single_set(void) {
Array *array = array_create(NULL);
array_set_value(array, 0, 42);
int size = array_get_size(array);
TEST_ASSERT_EQUAL(1, size);
array_deconstructor(&array);
}
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);
int size = array_get_size(array);
TEST_ASSERT_EQUAL(3, size);
array_deconstructor(&array);
}
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);
int size = array_get_size(array);
TEST_ASSERT_EQUAL(6, size);
array_deconstructor(&array);
}
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);
int size = array_get_size(array);
int capacity = array_get_capacity(array);
TEST_ASSERT_LESS_OR_EQUAL(capacity, size);
TEST_ASSERT_EQUAL(3, size);
TEST_ASSERT_EQUAL(10, capacity);
array_deconstructor(&array);
}
void test_array_get_size_after_resize_beyond_capacity(void) {
Array *array = array_create(&(ArrayCreateOptions){.initial_size = 5});
array_set_value(array, 0, 10);
array_set_value(array, 15, 100);
int size = array_get_size(array);
int capacity = array_get_capacity(array);
TEST_ASSERT_EQUAL(16, size);
TEST_ASSERT_LESS_OR_EQUAL(capacity, size);
array_deconstructor(&array);
}
int main(void)
{
UNITY_BEGIN();
@@ -40,6 +273,23 @@ int main(void)
RUN_TEST(test_array_create_without_options);
RUN_TEST(test_array_create_with_options);
RUN_TEST(test_array_deconstruct);
RUN_TEST(test_array_resize_expand);
RUN_TEST(test_array_resize_shrink);
RUN_TEST(test_array_set_value_within_capacity);
RUN_TEST(test_array_set_value_beyond_capacity);
RUN_TEST(test_array_get_value_valid_index);
RUN_TEST(test_array_get_value_zero_index);
RUN_TEST(test_array_get_value_beyond_capacity);
RUN_TEST(test_array_multiple_operations);
RUN_TEST(test_array_get_capacity_default);
RUN_TEST(test_array_get_capacity_custom_size);
RUN_TEST(test_array_get_capacity_after_resize);
RUN_TEST(test_array_get_size_initial);
RUN_TEST(test_array_get_size_after_single_set);
RUN_TEST(test_array_get_size_after_multiple_sets);
RUN_TEST(test_array_get_size_with_gap_in_indices);
RUN_TEST(test_array_get_size_capacity_relationship);
RUN_TEST(test_array_get_size_after_resize_beyond_capacity);
return UNITY_END();
}