I'm testing my array_list with some test: I need to check if my array list is empty after the de-allocation, but I have some problems
...
typedef struct array_list{
void** array;
size_t size;
size_t capacity;
}array_list_t;
array_list_t* array_list_new(size_t capacity) {
array_list_t* result = (array_list_t*) malloc(sizeof(array_list_t));
result->array = (void**) malloc(sizeof(void*)*capacity);
result->size = 0;
result->capacity = capacity;
return result;
}
void array_list_free(array_list_t* array) {
free(array->array);
free(array);
}
int array_list_is_empty(array_list_t* list){
if(list->size == 0){
return 1;
}else{
return 0;
}
}
#include "unity.h"
#include "array_list.h"
...
int main () {
array_list_t* array = array_list_new(10);
TEST_ASSERT_EQUAL_INT(1, array_list_is_empty(array)); // 1 == 1 OK
array_list_insert(array,new_int(1));
TEST_ASSERT_EQUAL_INT(0, array_list_is_empty(array)); // 0 == 0 OK
array_list_free(array);
TEST_ASSERT_EQUAL_INT(1, array_list_is_empty(array)); // 1 == 0 NOT_EQUAL
}
I thought to solve this problem setting the size as 0 after free, for example:
(... free(array); array->size = 0; array->capacity = 0; array = NULL; ...)
How do I solve this problem?
Once you do free(array)
in array_list_free()
, it's no longer valid to dereference array
. So you need to set the array
variable to NULL
in main()
:
array_list_free(array);
array = NULL;
Then array_list_is_empty()
can check whether its argument is NULL
before testing the size:
int array_list_is_empty(array_list_t *list) {
return list == NULL || list->size == 0;
}
A better design would be for array_list_free()
to just free array->array
, and allow the caller to do free(array)
when it's done with that array list. This is the usual approach: whichever component allocates an object is responsible for freeing it.