C – освобождение структур

Предположим, у меня есть эта структура

typedef struct person{ char firstName[100], surName[51] } PERSON; 

и я выделяю пространство malloc и заполняя его некоторыми значениями

 PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON)); strcpy(testPerson->firstName, "Jack"); strcpy(testPerson->surName, "Daniels"); 

Каков правильный и безопасный способ освободить всю память, занятую этой структурой? Является «бесплатным (testPerson)»; достаточно или мне нужно освободить атрибут каждой структуры один за другим?

Это приводит меня к другому вопросу – как хранятся структуры в памяти? Я заметил странное поведение – когда я пытаюсь напечатать адрес структуры, он равен адресу первого атрибута.

 printf("Structure address %d == firstName address %d", testPerson, testPerson->firstName); 

Это означает, что этот бесплатный (testPerson) должен быть равен этому свободному (testPerson-> firstName);

и это не то, что я хочу сделать.

благодаря

Простой ответ: free(testPerson) достаточно.

Помните, что вы можете использовать free() только тогда, когда вы выделили память с помощью malloc , calloc или realloc .

В вашем случае у вас есть только malloced memory для testPerson так что освобождения достаточно.

Если вы использовали char * firstname , *last surName тогда в этом случае для хранения имени вы должны были выделить память, и именно поэтому вы должны были освобождать каждого участника по отдельности.

Здесь также точка должна быть в обратном порядке; это означает, что память, выделенная для элементов, выполняется позже, поэтому free() она сначала освобождает указатель на объект.

Освобождая каждый элемент, вы можете увидеть демонстрацию, показанную ниже:

 typedef struct Person { char * firstname , *last surName; }Person; Person *ptrobj =malloc(sizeof(Person)); // memory allocation for struct ptrobj->fistname = malloc(n); // memory allocation for firstname ptrobj->surName = malloc(m); // memory allocation for surName . . // do whatever you want free(ptrobj->surName); free(ptrobj->firstname); free(ptrobj); 

Причина этого в том, что если вы сначала освободите ptrobj , тогда будет утечка памяти, которая является памятью, выделенной указателями suName и suName .

Поскольку вы определили struct как состоящую из массивов char , две строки являются структурой и освобождением struct достаточно, и нет способа освободить struct но сохранить массивы. В этом случае вы хотели бы сделать что-то вроде struct { char *firstName, *lastName; } struct { char *firstName, *lastName; } , но тогда вам нужно выделить память для имен отдельно и решить вопрос о том, когда освободить эту память.

Кроме того: есть ли причина, по которой вы хотите сохранить имена после освобождения структуры?

Сначала вы должны знать, сколько памяти выделяется при определении и распределении памяти в нижнем регистре.

  typedef struct person{ char firstName[100], surName[51] } PERSON; PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON)); 

1) Теперь sizeof (PERSON) возвращает 151 байт (не включает прописку)

2) Память 151 байт выделена в куче.

3) Чтобы бесплатно, позвоните бесплатно (testPerson).

но если вы объявите свою структуру как

  typedef struct person{ char *firstName, *surName; } PERSON; PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON)); 

тогда

1) sizeof (PERSON) теперь возвращает 8 байтов (не включает прописку)

2) Необходимо выделить память для firstName и surName, вызывая malloc () или calloc (). как

  testPerson->firstName = (char *)malloc(100); 

3) Чтобы освободить, сначала освободите членов в структуре, чем свободную структуру. т.е. free (testPerson-> firstName); бесплатно (testPerson-> ФАМИЛИЯ); бесплатно (testPerson);

Таким образом вам нужно освободить структуру, потому что поля представляют собой массивы со статическими размерами, которые будут распределены как часть структуры. Это также является причиной того, что адреса, которые вы видите, совпадают: массив является первым в этой структуре. Если вы объявили поля как char *, вам придется вручную malloc и освободить их.

Mallocs и frees должны быть в паре.

malloc схватил кусок памяти, достаточно большой для Лица.

Когда вы освобождаете, вы говорите malloc, что часть памяти, начинающаяся «здесь», больше не нужна, она знает, сколько она выделяет и освобождает ее.

Если вы позвоните

  free(testPerson) 

или

  free(testPerson->firstName) 

все, что free () фактически получает, это адрес, тот же адрес, он не может сказать, к кому вы звонили. Ваш код намного яснее, если вы используете free (testPerson), хотя это явно совпадает с malloc.

Вы не можете освобождать типы, которые не распределены динамически. Хотя массивы синтаксически похожи ( int* x = malloc(sizeof(int) * 4) можно использовать так же, как и int x[4] ), вызов free(firstName) , скорее всего, вызовет ошибку для последнего.

Например, возьмите этот код:

 int x; free(&x); 

free() – это функция, которая принимает указатель. &x – указатель. Этот код может компилироваться, хотя он просто не будет работать.

Если мы притворимся, что вся память распределена таким же образом, x «распределяется» по определению, «освобождается» во второй строке, а затем «освобождается» снова после окончания области. Вы не можете освободить тот же ресурс дважды; это даст вам сообщение об ошибке.

Это даже не говорит о том, что по определенным причинам вы не сможете освободить память в x без закрытия программы.

tl; dr: Просто освободите struct и все будет в порядке. Не звоните бесплатно на массивы; только называть его динамически распределенной памятью.

free недостаточно, free просто отмечает, что память не используется, данные структуры будут там до перезаписывания. Для безопасности установите указатель на NULL после free .

Пример:

 if (testPerson) { free(testPerson); testPerson = NULL; } 

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

  • Невозможно изменить ошибку возвращаемого значения c #
  • Почему «typdef struct {struct S * s; } S; ", содержащий указатель на компиляцию того же типа?
  • Как включить динамический массив INSIDE a struct в C?
  • Нечитаемая только альтернатива анонимным типам
  • Безопасно ли для структур создавать интерфейсы?
  • Как определить структуру typedef, содержащую указатели на себя?
  • Почему открытые поля быстрее, чем свойства?
  • ARC запрещает объекты Objective-C в структурах или объединениях, несмотря на маркировку файла -fno-objc-arc
  • Каковы различия между структурой и classом в C ++?
  • Макет в памяти структуры. структура массивов и массив структур в C / C ++
  • Изменить переменную Struct в словаре
  • Interesting Posts
    Давайте будем гением компьютера.