How to free a struct that contains only pointers

2019-02-02 02:42发布

问题:

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?

回答1:

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


回答2:

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



回答3:

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.



回答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.