Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - freeing structs

Tags:

c

malloc

struct

Let's say I have this struct

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

and I am allocating space by malloc and filling it with some values

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

What is the correct and safe way to free all memory taken by that struct? Is "free(testPerson);" enough or do I need to free each struct's attribute one by one?

It leads me to another question - how are structures stored in memory? I noticed a strange behaviour - when I try to print structure address it's equal to it's first attribute's address.

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

Which means that this free(testPerson) should be equal to this free(testPerson->firstName);

and that's not what I want to do.

Thanks

like image 949
user10099 Avatar asked Nov 27 '12 18:11

user10099


2 Answers

Simple answer : free(testPerson) is enough .

Remember you can use free() only when you have allocated memory using malloc, calloc or realloc.

In your case you have only malloced memory for testPerson so freeing that is sufficient.

If you have used char * firstname , *last surName then in that case to store name you must have allocated the memory and that's why you had to free each member individually.

Here is also a point it should be in the reverse order; that means, the memory allocated for elements is done later so free() it first then free the pointer to object.

Freeing each element you can see the demo shown below:

typedef struct Person { char * firstname , *last surName; }Person; Person *ptrobj =malloc(sizeof(Person)); // memory allocation for struct ptrobj->firstname = 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); 

The reason behind this is, if you free the ptrobj first, then there will be memory leaked which is the memory allocated by firstname and suName pointers.

like image 176
Omkant Avatar answered Nov 15 '22 23:11

Omkant


First you should know, how much memory is allocated when you define and allocate memory in below case.

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

1) The sizeof(PERSON) now returns 151 bytes (Doesn't include padding)

2) The memory of 151 bytes is allocated in heap.

3) To free, call free(testPerson).

but If you declare your structure as

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

then

1) The sizeof(PERSON) now returns 8 bytes (Doesn't include padding)

2) Need to allocate memory for firstName and surName by calling malloc() or calloc(). like

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

3) To free, first free the members in the struct than free the struct. i.e, free(testPerson->firstName); free(testPerson->surName); free(testPerson);

like image 45
Viswesn Avatar answered Nov 15 '22 22:11

Viswesn