Когда вы должны освободить память динамически выделяется? - PullRequest
2 голосов
/ 29 ноября 2011

По сути, я создал фрагмент кода, который состоит из дерева, в котором каждый узел дерева имеет свой собственный связанный список, содержащий данные (каждый узел дерева также содержит данные). Так что каждый treeNode может иметь несколько элементов данных для этого конкретного treeNode.

Для создания этой структуры я называю treenode, передаю адрес этого treenode в функцию createListNode и называю ListNode. Мое замешательство на самом деле происходит от того, где именно я должен освободить память? Только в конце программы до возврата 0; в основном или в другом месте. Имея в виду, что все входные данные добавлены в дерево и список, он запрашивает имя пользователя и отображает связанный список данных, соответствующих этому имени.

Приветствие.

T.C.

РЕДАКТИРОВАТЬ:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

typedef struct ListNode {
    char            *number;
    struct ListNode *next;
}ListNode;

typedef struct TreeNode {
    char            *name;
    ListNode        *numbers;
    struct TreeNode *left;
    struct TreeNode *right;
}TreeNode;

TreeNode* AddNode(TreeNode *, char *, char *);
void  AddNum(TreeNode *, char *);
void N_Print(TreeNode* root);
TreeNode* SearchTree(TreeNode* root, char *search);

int main(void) {
char my_string[50], name[25], number[25];
TreeNode *root = NULL;
while ((fgets(my_string, 50, stdin)) != NULL) {
        if (my_string[0] == '.')
            break;      
    sscanf(my_string, "%s %s", name, number); 
    root = AddNode(root, name, number);  
}   
N_Print(root);
free(root);
free(root->numbers);
return 0;
}

TreeNode* AddNode(TreeNode *root, char *name, char *number) {
int comparison;   
if (root == NULL) {
    root = (TreeNode*)calloc(1,sizeof(TreeNode));
    root->name = strdup(name); 
    root->left = root->right = NULL;      
    AddNum(root, number);
}else if ((comparison = strcasecmp(name, root->name)) < 0)
    root->left = AddNode(root->left, name, number);
else if ((comparison = strcasecmp(name, root->name)) > 0) {
    root->right = AddNode(root->right, name, number);
} else if ((comparison = strcasecmp(name, root->name)) == 0 ) {
    AddNum(root, number);
}       
return root;
}

void AddNum(TreeNode *tn, char *number) {
 ListNode *ln = (ListNode *)calloc(1, sizeof(ListNode));
 ln->number = strdup(number);
 ln->next = tn->numbers;
 tn->numbers = ln;
}

TreeNode* SearchTree(TreeNode* root, char *search) {
int comparison;
if (root == NULL) {
    return NULL;
} else if ((comparison = strcasecmp(search, root->name)) == 0) {
    return root;
} else if ((comparison = strcasecmp(search, root->name)) < 0) {
     return SearchTree(root->left, search);
} else if ((comparison = strcasecmp(search, root->name)) > 0) 
     return SearchTree(root->right, search);    
}

void N_Print(TreeNode* root) {
TreeNode* search_val;
char search[25];
while(1) {
    printf("Type a name please: ");
    scanf("%24s", search);
            if (search[0] == '.')
                    break;
    search_val = SearchTree(root, search); 
    if (search_val == NULL) {
        printf("NOT FOUND\n");
        continue;
    }
    ListNode* ln = search_val->numbers;
    while ( ln != NULL) {
            printf("%s\n", ln->number);
            ln = ln->next;
    }
}
}

Ответы [ 7 ]

4 голосов
/ 29 ноября 2011

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

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

3 голосов
/ 29 ноября 2011

Лучший план (IMO) - освободить память в том месте, где вам больше не нужен доступ к ней.однако, если вы используете только небольшое количество динамически выделенной памяти, это, вероятно, не будет иметь большого значения, если вы все сделаете в конце своей программы (при условии, что вы все это отслеживаете)

2 голосов
/ 29 ноября 2011

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

Если, например, связанные списки в дереве на каком-то этапе могут сжиматься, узлы, которые больше не используются, должны быть немедленно освобождены.

2 голосов
/ 29 ноября 2011

Вы можете освободить все данные, как только они вам больше не понадобятся, например, когда вы закончите их печатать.В вашем случае, если это все, что вы программируете, это не имеет значения, так как ваше ядро ​​освободит всю память, выделенную вашей программой при завершении.Однако важно, продолжает ли программа работать, поскольку это означает, что вы потребляете память, которую нельзя использовать для других программ.

Это немного похоже на предыдущую версию Firefox, где она не освобождала память после закрытия вкладки.Программа продолжала запрашивать все больше и больше памяти, не освобождая ее.

2 голосов
/ 29 ноября 2011

Когда вам больше не нужны ресурсы, приобретенные в бесплатном магазине.Таким образом, это зависит от того, в какой момент вы не используете ресурсы calloc , вы можете запустить free it.Но остерегайтесь свисающих ссылок.

2 голосов
/ 29 ноября 2011

Все просто:

Вы освобождаете память, когда она вам больше не нужна.В вашем случае кажется, что вам никогда не придется удалять узел, поэтому не беспокойтесь об его удалении.Он автоматически освобождается при выходе из вашей программы.Будьте осторожны, вы должны удалить всю память, все указатели, ссылающиеся на нее, выходят из области видимости, делая ее непригодной для использования.Это может привести к утечке памяти.

0 голосов
/ 30 ноября 2011

Как все говорят выше, освободите его, если он вам больше не нужен, но, кроме того, часто стоит попробовать бесплатно на том же уровне, что и вы.Это сложнее, когда вы передаете ссылки и тому подобное.

...