Как мне освободить динамически выделяемую память изнутри структуры?

#c #pointers

#c #указатели

Вопрос:

Я давно не пользовался C, и я все еще немного новичок в этом. Меня смущает синтаксис указателей и ссылок. По сути, у меня есть контейнер struct с указателями, которые я динамически выделяю в виде массивов. Я хочу знать, как освободить эту память, когда я закончу с этим. Вот как это выглядит:

 typedef struct {
    int* foo;
} Bar;

typedef Bar * BarRef;

BarRef newBar(int n) {
    BarRef B = malloc(sizeof(Bar));
    B->foo = calloc(n,sizeof(int));
}

/* This is what I am having trouble understanding */
void freeBar(BarRef *B) {
    free(B->foo);
    B->foo = NULL;
    free(B);
    *B = NULL;
}
  

Я получаю ошибку компилятора, сообщающую мне, что я запрашиваю элемент у чего-то, что не является структурой. Но я думал, что передача Ref* приведет к разыменованию, так что это будет похоже на передачу структуры. Я использую gcc и ANSI C.

Ответ №1:

 void freeBar(BarRef * B) {
    // Here B is a pointer to a pointer to a struct Bar. 
    // Since BarRef is Bar *
    // And B is a BarRef *
}
  

Поскольку вы хотите изменить указатель на struct Bar (установив указатель равным NULL), вы правильно передали значение BarRef *, но содержимое вашей процедуры должно выглядеть следующим образом:

 free((*B)->foo);
(*B)->foo = NULL;
free(*B);
*B = NULL;
  

(*B)->foo работает следующим образом:

(*B) Разыменования B, данные вам BarRef (ОН ЖЕ a Bar * ) (*B)->foo , обращаются к элементу, вызываемому foo в структуре bar, на которую указывает (*B)

B->foo недопустимо. Это означает доступ к элементу, вызываемому foo в структуре bar, на которую указывает B . Поскольку B это не указывает на структуру bar, а вместо этого указывает на pointer to a bar structure , вы получаете ошибку «запрашивающий элемент из чего-то, что не является структурой». «Что-то, что не является структурой» — это указатель на структуру.