Использование бесплатно с двойным указателем на структуру - PullRequest
1 голос
/ 21 января 2020

Я пытаюсь понять, как использовать функцию free. В следующем фрагменте я создаю ctx, используя malloc.

void serve(ctx **some_struct_type) {
     // .. some operation
}

int main() {

  context_t* ctx = malloc(sizeof(struct context_t));
  serve(&ctx);

}

Поскольку каждый вызов mallo c должен иметь соответствующий вызов free, и я хочу позвонить бесплатно внутри serve, это должно быть free((**ctx)) или free((*ctx))?

Я немного запутался в том, как я должен вызывать бесплатно.

Ответы [ 3 ]

1 голос
/ 21 января 2020

Вы объявили указатель в main

context_t* ctx = malloc(sizeof(struct context_t));

Чтобы освободить выделенную память в main, вы можете написать

free( ctx );

Однако вы передали указатель по ссылке на функцию serve

serve(&ctx);

Таким образом, чтобы получить ссылочный объект (указатель) в функции, необходимо разыменовать указатель, объявленный как параметр функции (я изменю параметр функции, чтобы иметь смысл для функции)

oid serve( context_t **p ) {

То есть вам нужно написать

free( *p );

, где *p - это lvalue исходного объекта ctx.

0 голосов
/ 21 января 2020
Функция

mallo c используется для выделения определенного объема памяти во время выполнения программы. Он отправляет запрос в ОС и, если это возможно, ОС зарезервирует запрошенный объем памяти из кучи. (функция возвращает адрес выделенного пространства)

+-------+------------------+------+----------------------+
| stack | -> free space <- | heap | data & code segments |
+-------+------------------+------+----------------------+

free работает по-другому, принимает адрес (ссылка) который указывает на некоторый блок памяти и освобождает его.

Если вы хотите, чтобы он был освобожден в main, вы бы сделали это следующим образом:

int main() {

  context_t* ctx = malloc(sizeof(struct context_t));
  free(ctx);

}

, но так как вы конвертируете его в удвоенный указатель (указатель на указатель) вам нужно разыменовать его обратно на адрес, который вы выделили:

int main() {

  context_t* ctx = malloc(sizeof(struct context_t));

  ctx **some_struct_type = &ctx;

  free(*some_struct_type);

}
0 голосов
/ 21 января 2020

В main значение ctx является адресом блока выделенной памяти. Именно это значение передается free.

. Если вы передаете адрес ctx в функцию, вам нужно разыменовать этот указатель, чтобы получить значение указателя, полученное из malloc ,

Таким образом, предполагая, что функция объявлена ​​как:

void serve(struct context_t **ctx) {

Вы хотите free(*ctx) внутри этой функции.

...