Как освободить структуру, которая содержит только указатели - PullRequest
10 голосов
/ 06 февраля 2011

У меня есть структура, которую вы видите ниже:

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

Есть ли необходимость в освобождении этой структуры?Если так, как я могу освободить это?

Ответы [ 4 ]

13 голосов
/ 06 февраля 2011

Вы должны освободить структуру, если вы разместили ее динамически. Вы должны освободить его члены перед освобождением структуры, если вы динамически распределяли члены и не имеете ссылки на них где-либо еще.

Вот несколько примеров:

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 );
}
4 голосов
/ 06 февраля 2011

Это зависит ...

Итак, вы спросили "... нужно ли освободить ...?" и ответ: "это зависит." Если структура нужна почти до тех пор, пока программа не завершится с помощью возврата из main(), exit() или сигнала, то нет она никогда не должна освобождаться независимо от того, что в нем. 1

Если ресурс выделяется динамически в долгоживущем процессе, таком как редактор или демон сервера, но если после транзакции или периода времени он больше не нужен, то yes , его нужно освободить, иначе у программы будет утечка памяти .

Освобождение структуры приведет к утечке памяти, если содержащиеся объекты также будут динамически размещаться. Либо вообще ничего не нужно освобождать, либо нужно освободить весь граф объектов с корнем в этой структуре.

Правило простое, каждый человек malloc() должен соответствовать одному человеку free().


1. Сказав это, обычно привлекает небольшой поток доктринеров "Вы должны освободить все" протест, но такой протест частично дезинформирован. C ++ Faq хорошо обсуждает проблему . Одной из проблем является то, что медленно и бессмысленно вставлять или касаться множества страниц, которые ОС может освободить как блок. Но да, есть аргумент, что это хороший шаблон проектирования, хорошая практика, и если есть какая-либо возможность включить код во вторую программу, память всегда должна быть освобождена.

4 голосов
/ 06 февраля 2011
void free_mystruct(struct_List *a_ptr){
  free(a_ptr->person);
  free(a_ptr->do);
  free(a_ptr);
}

, если вы использовали malloc для первоначального выделения памяти.

4 голосов
/ 06 февраля 2011

Если вы выделили объект с помощью malloc(), то вам нужно free() в какой-то момент.

...