C бесплатно и структура - PullRequest
13 голосов
/ 17 июля 2011

Мой вопрос касается функции C free () для освобождения блоков памяти, ранее выделенных с помощью malloc ().
Если у меня есть тип данных struct, состоящий из нескольких указателей, каждый из которых указывает на разные области памяти, что произойдетв эти места памяти, если я применяю free () на структуру?эти места тоже будут бесплатными?или просто блок памяти, который выделяет указатель?

Ответы [ 4 ]

23 голосов
/ 17 июля 2011

Нет.Они не будут освобождены.Вы должны освободить их "вручную".Malloc ничего не знает о содержимом вашей структуры (он вообще не знает, что это структура, это просто «кусок памяти» с ее точки зрения).

9 голосов
/ 17 июля 2011

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

Вы можете использовать valgrind (если есть), чтобы убедиться в этом:

#include <stdlib.h>

struct resources{
   int * aint;
   double * adouble;
};                                                                              
int main(){

   int* someint = malloc(sizeof(int) * 1024);
   double* somedouble = malloc(sizeof(double)* 1024);

   struct resources *r  = malloc(sizeof(struct resources));

   r->aint = someint;
   r->adouble = somedouble;

   free (r);
   return 0;

}

$ gcc test_struct.c -o test
$ valgrind ./test
==9192== Memcheck, a memory error detector
==9192== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==9192== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==9192== Command: ./test
==9192== 
==9192== 
==9192== HEAP SUMMARY:
==9192==     in use at exit: 12,288 bytes in 2 blocks
==9192==   total heap usage: 3 allocs, 1 frees, 12,296 bytes allocated
==9192== 
==9192== LEAK SUMMARY:
==9192==    definitely lost: 12,288 bytes in 2 blocks
==9192==    indirectly lost: 0 bytes in 0 blocks
==9192==      possibly lost: 0 bytes in 0 blocks
==9192==    still reachable: 0 bytes in 0 blocks
==9192==         suppressed: 0 bytes in 0 blocks
==9192== Rerun with --leak-check=full to see details of leaked memory
==9192== 
==9192== For counts of detected and suppressed errors, rerun with: -v
==9192== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 7)
3 голосов
/ 17 июля 2011
struct Node
{
  struct Node *nextSibling;
  struct Node *prevSibling;
  struct Node *parentNode;
  ...
};
...
struct Node *rootNode;
/* Initialize `rootNode' and fill in its various fields;
   do the same with more nodes.  */

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

0 голосов
/ 27 июня 2013

Просто чтобы прояснить ответ @Chrono Kitsune, все еще можно освободить указатели внутри структуры, но это рискованно.

То, что делает free(rootNode), на самом деле говорит блоку управления памятью, что пространство памяти, которое использовалось rootNode, больше не используется и является честной игрой для всего, что в этом нуждается. Хотя rootNode все еще указывает на то же место, теперь он считается недействительным указателем, и его содержимое может быть повреждено, поскольку его местоположение теперь может быть перезаписано другими вещами.

Если вы попытаетесь получить доступ к rootNode сразу после его освобождения, оно может работать, но нет гарантии, поэтому безопаснее всего free его содержимое (которое было malloc 'd) до удаления rootNode.

...