释放后如何将arraylist设置为空?

How to set arraylist as empty after free?

我正在通过一些测试来测试我的 array_list: 我需要在取消分配后检查我的数组列表是否为空, 但我有一些问题


...
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
}

我想解决这个问题,在 free 后将大小设置为 0, 例如:

(... free(array); array->size = 0; array->capacity = 0; array = NULL; ...)

如何解决这个问题?

i'm testing my array_list with some test: I need to check if my array list is empty after the deallocation, but i have some problems

是的,您有一个无法克服的问题:一旦您像 array_list_free 那样释放 array_list_t 结构,尝试访问它会产生未定义的行为。因此,此时您尝试对其执行的任何测试的结果都不会产生任何有用的信息(因为:undefined),并且该尝试可能会产生您能力范围内的任何结果C 实现,完全有可能使程序崩溃。

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; ...)

这是 清除 列表而不释放它的一个很好的替代方法。特别是,将容量设置为 0 是元素数组需要(重新)分配的自然指示。但是同样,一旦您释放了列表结构本身,您就不能或应该对它做更多的事情了。它的寿命结束了。它踢了水桶,摆脱了致命的束缚,运行 落下帷幕,加入了无形的流血合唱团!!这是一个前列表! (向蒙蒂道歉Python)

一旦您在 array_list_free() 中执行 free(array),取消引用 array 将不再有效。所以需要在main():

中设置array变量为NULL
array_list_free(array);
array = NULL;

然后array_list_is_empty()可以在测试大小之前检查其参数是否为NULL

int array_list_is_empty(array_list_t *list) {
    return list == NULL || list->size == 0;
}

更好的设计是 array_list_free() 只释放 array->array,并允许调用者在完成该数组列表后执行 free(array)。这是通常的方法:分配对象的组件负责释放它。

您可以在调用 array_list_free(a) 后执行 a=NULL; 以指示 a 不再可用。

或者您可以将 array_list_free(a) 修改为不释放 a,而是将 a->capacity 和 a->size 设置为 0,并将 a->array 设置为 NULL,将 *a 留空看状态。