C - freeing structs

后端 未结 7 1593
孤独总比滥情好
孤独总比滥情好 2020-11-30 19:43

Let\'s say I have this struct

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

and I am allocating space by malloc and

相关标签:
7条回答
  • 2020-11-30 19:50

    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);

    0 讨论(0)
  • 2020-11-30 20:02

    Mallocs and frees need to be paired up.

    malloc grabbed a chunk of memory big enough for Person.

    When you free you tell malloc the piece of memory starting "here" is no longer needed, it knows how much it allocated and frees it.

    Whether you call

     free(testPerson) 
    

    or

     free(testPerson->firstName)
    

    all that free() actually receives is an address, the same address, it can't tell which you called. Your code is much clearer if you use free(testPerson) though - it clearly matches up the with malloc.

    0 讨论(0)
  • 2020-11-30 20:03

    You can't free types that aren't dynamically allocated. Although arrays are syntactically similar (int* x = malloc(sizeof(int) * 4) can be used in the same way that int x[4] is), calling free(firstName) would likely cause an error for the latter.

    For example, take this code:

    int x;
    free(&x);
    

    free() is a function which takes in a pointer. &x is a pointer. This code may compile, even though it simply won't work.

    If we pretend that all memory is allocated in the same way, x is "allocated" at the definition, "freed" at the second line, and then "freed" again after the end of the scope. You can't free the same resource twice; it'll give you an error.

    This isn't even mentioning the fact that for certain reasons, you may be unable to free the memory at x without closing the program.

    tl;dr: Just free the struct and you'll be fine. Don't call free on arrays; only call it on dynamically allocated memory.

    0 讨论(0)
  • 2020-11-30 20:06

    free is not enough, free just marks the memory as unused, the struct data will be there until overwriting. For safety, set the pointer to NULL after free.

    Ex:

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

    struct is similar like an array, it is a block of memory. You can access to struct member via its offset. The first struct's member is placed at offset 0 so the address of first struct's member is same as the address of struct.

    0 讨论(0)
  • 2020-11-30 20:08

    This way you only need to free the structure because the fields are arrays with static sizes which will be allocated as part of the structure. This is also the reason that the addresses you see match: the array is the first thing in that structure. If you declared the fields as char * you would have to manually malloc and free them as well.

    0 讨论(0)
  • 2020-11-30 20:13

    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.

    0 讨论(0)
提交回复
热议问题