refactor dynamic array: update index types to size_t for better compatibility and memory safety
This commit is contained in:
@@ -25,7 +25,7 @@ void array_deconstructor(Array **pp_array) {
|
|||||||
*pp_array = NULL;
|
*pp_array = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void array_resize(Array *p_array, const int new_size) {
|
void array_resize(Array *p_array, const size_t new_size) {
|
||||||
int *new_ptr = realloc(p_array->value, new_size*p_array->element_size);
|
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);
|
||||||
@@ -39,16 +39,16 @@ void array_resize(Array *p_array, const int new_size) {
|
|||||||
p_array->capacity = new_size;
|
p_array->capacity = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *array_get_value(const Array *p_array, const int index) {
|
void *array_get_value(const Array *p_array, const size_t index) {
|
||||||
if (index > p_array->capacity) {
|
if (index > p_array->capacity) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return p_array->value + index * p_array->element_size;
|
return p_array->value + index * p_array->element_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void array_set_value(Array *p_array, const int index, const void *value) {
|
void array_set_value(Array *p_array, const size_t index, const void *value) {
|
||||||
if (index > p_array->capacity) {
|
if (index > p_array->capacity) {
|
||||||
int new_size = p_array->capacity;
|
size_t new_size = p_array->capacity;
|
||||||
while (index >= new_size) {
|
while (index >= new_size) {
|
||||||
new_size *= 2;
|
new_size *= 2;
|
||||||
}
|
}
|
||||||
@@ -62,10 +62,10 @@ void array_set_value(Array *p_array, const int index, const void *value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int array_get_size(const Array *p_array) {
|
size_t array_get_size(const Array *p_array) {
|
||||||
return p_array->size;
|
return p_array->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int array_get_capacity(const Array *p_array) {
|
size_t array_get_capacity(const Array *p_array) {
|
||||||
return p_array->capacity;
|
return p_array->capacity;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,16 @@
|
|||||||
#define DEFAULT_ARRAY_SIZE 10
|
#define DEFAULT_ARRAY_SIZE 10
|
||||||
|
|
||||||
|
|
||||||
typedef struct Array {
|
typedef struct {
|
||||||
void *value;
|
void *value;
|
||||||
size_t element_size;
|
size_t element_size;
|
||||||
|
|
||||||
int size;
|
size_t size;
|
||||||
int capacity;
|
size_t capacity;
|
||||||
} Array;
|
} Array;
|
||||||
|
|
||||||
|
|
||||||
typedef struct ArrayCreateOptions {
|
typedef struct {
|
||||||
int initial_size;
|
int initial_size;
|
||||||
size_t element_size;
|
size_t element_size;
|
||||||
} ArrayCreateOptions;
|
} ArrayCreateOptions;
|
||||||
@@ -27,16 +27,28 @@ Array *array_create(const ArrayCreateOptions *options);
|
|||||||
void array_deconstructor(Array **pp_array);
|
void array_deconstructor(Array **pp_array);
|
||||||
|
|
||||||
|
|
||||||
void array_resize(Array *p_array, int new_size);
|
void array_resize(Array *p_array, size_t new_size);
|
||||||
|
|
||||||
|
|
||||||
void *array_get_value(const Array *p_array, int index);
|
void *array_get_value(const Array *p_array, size_t index);
|
||||||
|
|
||||||
|
|
||||||
void array_set_value(Array *p_array, int index, const void *value);
|
void array_set_value(Array *p_array, size_t index, const void *value);
|
||||||
|
|
||||||
|
|
||||||
int array_get_size(const Array *p_array);
|
size_t array_get_size(const Array *p_array);
|
||||||
|
|
||||||
|
|
||||||
int array_get_capacity(const Array *p_array);
|
size_t array_get_capacity(const Array *p_array);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define array_get_value_as(type, arr, idx) \
|
||||||
|
(sizeof(type) == (arr)->element_size) ? \
|
||||||
|
(type*)array_get_value(arr, idx) : \
|
||||||
|
NULL
|
||||||
|
|
||||||
|
#define array_set_value_as(type, arr, idx, value) \
|
||||||
|
((sizeof(type) == (arr)->element_size) ? \
|
||||||
|
(array_set_value((arr), (idx), (value)), 0) : \
|
||||||
|
-1)
|
||||||
@@ -35,7 +35,7 @@ void test_array_deconstruct(void) {
|
|||||||
|
|
||||||
void test_array_resize_expand(void) {
|
void test_array_resize_expand(void) {
|
||||||
Array *array = array_create(NULL);
|
Array *array = array_create(NULL);
|
||||||
const int ORIGINAL_CAPACITY = array->capacity;
|
const size_t ORIGINAL_CAPACITY = array->capacity;
|
||||||
const int NEW_CAPACITY = 30;
|
const int NEW_CAPACITY = 30;
|
||||||
|
|
||||||
array_resize(array, NEW_CAPACITY);
|
array_resize(array, NEW_CAPACITY);
|
||||||
@@ -78,7 +78,7 @@ void test_array_set_value_beyond_capacity(void) {
|
|||||||
Array *p_array = array_create(NULL);
|
Array *p_array = array_create(NULL);
|
||||||
const int INDEX = 50;
|
const int INDEX = 50;
|
||||||
const int EXPECTED_VALUE = 99;
|
const int EXPECTED_VALUE = 99;
|
||||||
const int ORIGINAL_CAPACITY = p_array->capacity;
|
const size_t ORIGINAL_CAPACITY = p_array->capacity;
|
||||||
|
|
||||||
array_set_value(p_array, INDEX, &EXPECTED_VALUE);
|
array_set_value(p_array, INDEX, &EXPECTED_VALUE);
|
||||||
|
|
||||||
@@ -155,7 +155,7 @@ void test_array_multiple_operations(void) {
|
|||||||
void test_array_get_capacity_default(void) {
|
void test_array_get_capacity_default(void) {
|
||||||
Array *array = array_create(NULL);
|
Array *array = array_create(NULL);
|
||||||
|
|
||||||
int capacity = array_get_capacity(array);
|
const size_t capacity = array_get_capacity(array);
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL(DEFAULT_ARRAY_SIZE, capacity);
|
TEST_ASSERT_EQUAL(DEFAULT_ARRAY_SIZE, capacity);
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ void test_array_get_capacity_custom_size(void) {
|
|||||||
const int EXPECTED_CAPACITY = 25;
|
const int EXPECTED_CAPACITY = 25;
|
||||||
Array *array = array_create(&(ArrayCreateOptions){.initial_size = EXPECTED_CAPACITY});
|
Array *array = array_create(&(ArrayCreateOptions){.initial_size = EXPECTED_CAPACITY});
|
||||||
|
|
||||||
int capacity = array_get_capacity(array);
|
const size_t capacity = array_get_capacity(array);
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL(EXPECTED_CAPACITY, capacity);
|
TEST_ASSERT_EQUAL(EXPECTED_CAPACITY, capacity);
|
||||||
|
|
||||||
@@ -177,11 +177,11 @@ void test_array_get_capacity_custom_size(void) {
|
|||||||
|
|
||||||
void test_array_get_capacity_after_resize(void) {
|
void test_array_get_capacity_after_resize(void) {
|
||||||
Array *array = array_create(NULL);
|
Array *array = array_create(NULL);
|
||||||
const int ORIGINAL_CAPACITY = array_get_capacity(array);
|
const size_t ORIGINAL_CAPACITY = array_get_capacity(array);
|
||||||
const int NEW_CAPACITY = 50;
|
const size_t NEW_CAPACITY = 50;
|
||||||
|
|
||||||
array_resize(array, NEW_CAPACITY);
|
array_resize(array, NEW_CAPACITY);
|
||||||
int capacity = array_get_capacity(array);
|
const size_t capacity = array_get_capacity(array);
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL(NEW_CAPACITY, capacity);
|
TEST_ASSERT_EQUAL(NEW_CAPACITY, capacity);
|
||||||
TEST_ASSERT_NOT_EQUAL(ORIGINAL_CAPACITY, capacity);
|
TEST_ASSERT_NOT_EQUAL(ORIGINAL_CAPACITY, capacity);
|
||||||
@@ -193,7 +193,7 @@ void test_array_get_capacity_after_resize(void) {
|
|||||||
void test_array_get_size_initial(void) {
|
void test_array_get_size_initial(void) {
|
||||||
Array *array = array_create(NULL);
|
Array *array = array_create(NULL);
|
||||||
|
|
||||||
int size = array_get_size(array);
|
const size_t size = array_get_size(array);
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL(0, size);
|
TEST_ASSERT_EQUAL(0, size);
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ void test_array_get_size_after_single_set(void) {
|
|||||||
const int VALUE = 42;
|
const int VALUE = 42;
|
||||||
|
|
||||||
array_set_value(array, 0, &VALUE);
|
array_set_value(array, 0, &VALUE);
|
||||||
int size = array_get_size(array);
|
const size_t size = array_get_size(array);
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL(1, size);
|
TEST_ASSERT_EQUAL(1, size);
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ void test_array_get_size_after_multiple_sets(void) {
|
|||||||
array_set_value(array, 0, &VALUE);
|
array_set_value(array, 0, &VALUE);
|
||||||
array_set_value(array, 1, &VALUE);
|
array_set_value(array, 1, &VALUE);
|
||||||
array_set_value(array, 2, &VALUE);
|
array_set_value(array, 2, &VALUE);
|
||||||
int size = array_get_size(array);
|
const size_t size = array_get_size(array);
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL(3, size);
|
TEST_ASSERT_EQUAL(3, size);
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ void test_array_get_size_with_gap_in_indices(void) {
|
|||||||
|
|
||||||
array_set_value(array, 0, &VALUE);
|
array_set_value(array, 0, &VALUE);
|
||||||
array_set_value(array, 5, &VALUE);
|
array_set_value(array, 5, &VALUE);
|
||||||
int size = array_get_size(array);
|
const size_t size = array_get_size(array);
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL(6, size);
|
TEST_ASSERT_EQUAL(6, size);
|
||||||
|
|
||||||
@@ -255,8 +255,8 @@ void test_array_get_size_capacity_relationship(void) {
|
|||||||
array_set_value(array, 1, &VALUE);
|
array_set_value(array, 1, &VALUE);
|
||||||
array_set_value(array, 2, &VALUE);
|
array_set_value(array, 2, &VALUE);
|
||||||
|
|
||||||
int size = array_get_size(array);
|
const size_t size = array_get_size(array);
|
||||||
int capacity = array_get_capacity(array);
|
const size_t capacity = array_get_capacity(array);
|
||||||
|
|
||||||
TEST_ASSERT_LESS_OR_EQUAL(capacity, size);
|
TEST_ASSERT_LESS_OR_EQUAL(capacity, size);
|
||||||
TEST_ASSERT_EQUAL(3, size);
|
TEST_ASSERT_EQUAL(3, size);
|
||||||
@@ -273,8 +273,8 @@ void test_array_get_size_after_resize_beyond_capacity(void) {
|
|||||||
|
|
||||||
array_set_value(array, 0, &VALUE);
|
array_set_value(array, 0, &VALUE);
|
||||||
array_set_value(array, 15, &VALUE);
|
array_set_value(array, 15, &VALUE);
|
||||||
const int size = array_get_size(array);
|
const size_t size = array_get_size(array);
|
||||||
const int capacity = array_get_capacity(array);
|
const size_t 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);
|
||||||
@@ -283,6 +283,62 @@ void test_array_get_size_after_resize_beyond_capacity(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_array_get_value_as(void) {
|
||||||
|
Array *p_array = array_create(&(ArrayCreateOptions){
|
||||||
|
.initial_size = 5,
|
||||||
|
.element_size = sizeof(int)
|
||||||
|
});
|
||||||
|
const int VALUE = 42;
|
||||||
|
|
||||||
|
array_set_value(p_array, 0, &VALUE);
|
||||||
|
|
||||||
|
const int *value = array_get_value_as(int, p_array, 0);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(VALUE, *value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_array_get_value_as_invalid_type(void) {
|
||||||
|
Array *p_array = array_create(&(ArrayCreateOptions){
|
||||||
|
.initial_size = 5,
|
||||||
|
.element_size = sizeof(int)
|
||||||
|
});
|
||||||
|
const int VALUE = 42;
|
||||||
|
|
||||||
|
array_set_value(p_array, 0, &VALUE);
|
||||||
|
|
||||||
|
const void *value = array_get_value_as(double, p_array, 0);
|
||||||
|
|
||||||
|
TEST_ASSERT_NULL(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_array_set_value_as(void) {
|
||||||
|
Array *p_array = array_create(&(ArrayCreateOptions){
|
||||||
|
.initial_size = 5,
|
||||||
|
.element_size = sizeof(double)
|
||||||
|
});
|
||||||
|
|
||||||
|
const double VALUE = 42;
|
||||||
|
|
||||||
|
const int result = array_set_value_as(double, p_array, 0, &VALUE);
|
||||||
|
TEST_ASSERT_EQUAL(result, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_array_set_value_as_invalid_type(void) {
|
||||||
|
Array *p_array = array_create(&(ArrayCreateOptions){
|
||||||
|
.initial_size = 5,
|
||||||
|
.element_size = sizeof(double)
|
||||||
|
});
|
||||||
|
|
||||||
|
const int VALUE = 42;
|
||||||
|
|
||||||
|
const int result = array_set_value_as(double, p_array, 0, &VALUE);
|
||||||
|
TEST_ASSERT_EQUAL(result, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UNITY_BEGIN();
|
UNITY_BEGIN();
|
||||||
@@ -307,6 +363,10 @@ int main(void)
|
|||||||
RUN_TEST(test_array_get_size_with_gap_in_indices);
|
RUN_TEST(test_array_get_size_with_gap_in_indices);
|
||||||
RUN_TEST(test_array_get_size_capacity_relationship);
|
RUN_TEST(test_array_get_size_capacity_relationship);
|
||||||
RUN_TEST(test_array_get_size_after_resize_beyond_capacity);
|
RUN_TEST(test_array_get_size_after_resize_beyond_capacity);
|
||||||
|
RUN_TEST(test_array_get_value_as);
|
||||||
|
RUN_TEST(test_array_get_value_as_invalid_type);
|
||||||
|
RUN_TEST(test_array_set_value_as);
|
||||||
|
RUN_TEST(test_array_set_value_as_invalid_type);
|
||||||
|
|
||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user