Как установить arraylist как пустой после освобождения? - PullRequest
1 голос
/ 03 мая 2019

Я тестирую свой 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
}

Я решил решить эту проблему, установив размер равным 0 после освобождения, например:

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

Как мне решить эту проблему?

Ответы [ 3 ]

2 голосов
/ 03 мая 2019

Как только вы введете free(array) в array_list_free(), оно больше не будет использоваться для разыменования array. Поэтому вам нужно установить переменную array на NULL в main():

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), когда это будет сделано с этим списком массивов. Это обычный подход: любой компонент, выделяющий объект, отвечает за его освобождение.

1 голос
/ 03 мая 2019

Я тестирую свой список массивов с помощью некоторого теста: мне нужно проверить, пуст ли мой список массивов после освобождения, но у меня есть некоторые проблемы

Да, у вас есть непреодолимаяпроблема: как только вы освобождаете структуру array_list_t, как это делает array_list_free, попытка доступа к ней приводит к неопределенному поведению.Таким образом, результат любого теста, который вы пытаетесь выполнить на этом этапе, не дает никакой полезной информации (потому что: undefined ), и попытка может иметь любой результат в рамках вашей реализации C, ссбой программы - вполне вероятная возможность.

Я решил решить эту проблему, установив размер равным 0 после освобождения, например: (... free (array); array-> size = 0; массив-> емкость = 0; массив = NULL; ...)

Это хорошая альтернатива для очистки списка без его освобождения.В частности, установка емкости в 0 является естественным признаком того, что массив элементов должен быть (пере) распределен.Но опять же, как только вы освободите саму структуру списка, вы больше ничего не можете и не должны с ней делать.Это время жизни прошло.Это пнуло ведро, это сорвало его смертную катушку, сбежало вниз по занавесу и присоединилось к кровоточащему хору невидимому !!ЭТО ЭКС-СПИСОК !!(Извинения Монти Пайтону)

0 голосов
/ 03 мая 2019

вы можете сделать a=NULL; после вызова array_list_free(a), чтобы указать, что a больше не используется.

Или вы можете изменить array_list_free(a), чтобы не освободить a, но вместо этого установить a- >acity и a-> size в 0 и установить a-> array в NULL, оставив * a в пустом состоянии.

...