бесплатно () следовать указателям?

Я уверен, что этого не происходит, но, возможно, в нем есть черная магия, вот мой вопрос:

Если у меня есть такая структура:

struct mystr { char * strp, unsigned int foo, }; 

и я выделяю для него память и хочу ее позже выпустить. Должен ли я делать

 free(mystr_var->strp); free(mystr_var); 

или последняя строка достаточно, выполняет ли функция free() указатели и освобождает их?

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

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

Если вы просто освобождаетесь от указателя struct, память структуры освобождается. Память, удерживаемая char* strp , становится утечкой памяти в вашей жизненной программе.

Нет, бесплатно не следует указателям, вам нужны обе строки.

Обычно я пишу функцию вроде:

 void freemystr(mystr *mystr_var) { if (mystr_var) { free(mystr_var->strp); mystr_var->strp = NULL; free(mystr_var); } } 

Нет, нет.

Это совсем не волшебство, для компилятора это просто еще один вызов функции.

Спросите себя, как вы будете использовать void free(void *); таким образом, что следует за указателями, конечно, не обманываясь тем, что ему дается блок двоичных данных, содержащий что-либо . Вы не можете.

Нет. Это просто освобождает блок, на который указывает.

Вам нужно явно освободить ссылочную память. Вам нужно сделать это сначала (то есть, скорее всего, в противоположном направлении к тому, как вы выделили память)

Нет. free не будет делать рекурсивный бесплатный для всех участников. Вы должны явно освободить всех членов, для которых вы выделили память.

Если вы понимаете, как распределена память для структуры и как бесплатные работы, это не будет проблемой.

 struct mystr { char * strp, unsigned int foo, }; 

когда вы выделили память с помощью malloc & friends, она выделяет только память для членов. В вашем случае один char* и один unsigned int . Обратите внимание, что он не выделяет никакой памяти для хранения данных в char* . Поэтому перед хранением данных вам необходимо снова выделить память для strp . За исключением случаев, когда вы напрямую назначаете строковые литералы или просто используйте указатель strp для указания на существующую память.

Пример:

Случай 1:

 struct mystr s; s.strp = "literals"; // valid, no need to malloc 

случай 2:

 char *p="abc"; s.strp = p; // valid, no need to malloc 

Во всех других случаях вы должны выделить память для strp перед хранением данных в strp .

Поэтому, когда вы вызываете free на переменную struct, она освобождает только указатель, выделенный для strp а не память, на которую указывает strp . Это просто потому, что у free нет информации о том, на что указывает strp .

Обратите внимание, что в приведенных выше двух примерах вы не освобождаете strp как вы не выделяли какую-либо память для хранения данных в strp . Простое правило является бесплатным для одного malloc/calloc/realloc .

C99 говорит,

Свободная функция заставляет пространство, на которое указывает ptr, освобождается, то есть становится доступным для дальнейшего выделения. Если ptr является нулевым указателем, никаких действий не происходит. В противном случае, если аргумент не соответствует указателю, ранее возвращенному функцией calloc, malloc или realloc, или если пространство было освобождено вызовом free или realloc, поведение не определено.