11

I have a struct which you see below:

typedef struct _List {
    Person *person; // pointer for people list
    DoList *do; // Kinda timer, for checking list in some intervals
} List;

Are there any need to free this struct? If so, how can i free it?

wonnie
  • 459
  • 3
  • 6
  • 19
  • The code you have shown, is a type definition. Free'ing a type makes no semantic sense, you can only free instances of a type, and then only if they were dynamically allocated. As such this question makes no sense at all. The fact that the structure contains pointers is irellevant - data is data; however you may need to free data that the pointers point to *before* freeing the structure instance itself. The answer depends on context, and you have provided no context. – Clifford Feb 06 '11 at 19:02

4 Answers4

14

You have to free the struct if you allocated it dynamically. You have to free its members before deallocating the struct if you allocated the members dynamically and don't have a reference to them anywhere else.

Here are some examples:

void freeNotRequiredHere() {
    List            nonDynamicList;
    Person          nonDynamicPerson;
    DoList          nonDynamicDoList;

    nonDynamicList.person = &nonDynamicPerson;
    nonDynamicList.do = &nonDynamicDoList;
}


void freeRequiredForStructListOnly() {
    List            *dynamicList;
    Person          nonDynamicPerson;
    DoList          nonDynamicDoList;

    dynamicList = (List *) malloc( sizeof(struct List) );

    dynamicList->person = &nonDynamicPerson;
    dynamicList->do = &nonDynamicDoList;

    free( dynamicList );
}


void freeRequiredForStructListAndPersonOnly() {
    List            *dynamicList;
    Person          *dynamicPerson;
    DoList          nonDynamicDoList;

    dynamicList = (List *) malloc( sizeof(struct List) );
    dynamicPerson = (Person *) malloc( sizeof(Person) );

    dynamicList->person = dynamicPerson;
    dynamicList->do = &nonDynamicDoList;

    free( dynamicPerson );
    free( dynamicList );
}


void freeRequiredForStructListAndPersonOnly( DoList *notSureDoList ) {
    List            *dynamicList;
    Person          *dynamicPerson;

    dynamicList = (List *) malloc( sizeof(struct List) );
    dynamicPerson = (Person *) malloc( sizeof(Person) );

    dynamicList->person = dynamicPerson;
    dynamicList->do = notSureDoList;

    // maybe notSureDoList was allocated with malloc(),
    // maybe it is a non-dynamic stack variable.
    // the calling function should deal with free()'ing notSureDoList

    free( dynamicPerson );
    free( dynamicList );
}
par
  • 17,361
  • 4
  • 65
  • 80
  • Let me show you how i used the malloc: List *l; l = malloc(sizeof(List)); l->person = personpointer; l->do = add_timer(personpointer, 15); – wonnie Feb 06 '11 at 19:00
  • From your example, yes, you need to free() l. You must free() anything you allocate with malloc(). Before you free() it though you'll probably want to do the equivalent of remove_timer() on l->do since l and its members (the person and do pointers themselves, not the things person and do point to) will no longer be valid after the free(). – par Feb 06 '11 at 19:12
  • But the OP asked *"any need to free this?".* And that answer depends on whether the object is needed until the program plans to `exit(2)`. If so, then it does *not* need to be freed. The OS will do it, and do it much faster. – DigitalRoss Aug 06 '12 at 17:56
  • @DigitalRoss - From a maintainability perspective, particularly if someone comes along later and copy/pastes or extends your code, it is an overwhelmingly good idea (and programming best practice) to free what you allocate and *not* rely on exit() to clean up after you. Your comment isn't wrong per-se, it's just not tidy and there's a good chance being lazy by not properly freeing what you malloc will cause problems for someone, somewhere, later. [edit: I see you addressed my comment as an edit to your answer below; since this question is for beginners I'll leave my comment]. – par Sep 09 '12 at 23:16
5
void free_mystruct(struct_List *a_ptr){
  free(a_ptr->person);
  free(a_ptr->do);
  free(a_ptr);
}

if you used malloc to initially allocate memory.

ayush
  • 14,350
  • 11
  • 53
  • 100
4

If you have allocated an object using malloc(), then you need to free() it at some point.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
4

It depends...

So you asked "...any need to free...?" and the answer is "it depends."

  • If the struct is needed almost until the program terminates via a return from main(), exit(), or a signal, then no it should never be freed regardless of what is in it.1

  • If the resource is allocated dynamically in a long-lived process such as an editor or server daemon, but if after a transaction or period of time it is no longer needed, then yes, it does need to be freed or the program will have a memory leak.

  • Freeing the structure will produce a memory leak if the contained objects are also dynamically allocated. Either nothing at all should be freed or the entire graph of objects with a root at that structure will need to be freed.

The rule is simple, each individual malloc() must correspond to a single individual free().


1. Saying this generally attracts a small flood of doctrinaire "you must free everything" protest, but such protest is partly misinformed. The C++ Faq discusses the issue well. One concern is that it's slow and pointless to page in or touch lots of pages that the OS is able to free as a block. But yes, there is an argument that it's a good design pattern, good practice, and if there is any possibility of incorporating the code into a second program then memory should be freed always.

DigitalRoss
  • 143,651
  • 25
  • 248
  • 329