Подтвердить что ты не робот

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)"; достаточно или мне нужно освободить каждый атрибут struct один за другим?

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

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

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

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

Спасибо

4b9b3361

Ответ 1

Простой ответ: 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, тогда будет утечка памяти, которая является памятью, выделенной указателями firstname и suName.

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

   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) Чтобы освободить, сначала освободите членов в структуре, чем свободную структуру. то есть,          бесплатно (testPerson- > Firstname);          бесплатно (testPerson- > ФАМИЛИЯ);          свободный (testPerson);

Ответ 5

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

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

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

Вызов

 free(testPerson) 

или

 free(testPerson->firstName)

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

Ответ 6

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

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

int x;
free(&x);

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

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

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

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

Ответ 7

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

Пример:

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

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