什么时候应该释放动态分配的内存?

时间:2011-11-28 23:34:55

标签: c memory dynamic calloc

本质上,我创建了一段由树组成的代码,每个树节点都有自己的包含数据的链表(每个treeNode也包含数据)。这样每个treeNode可以拥有该特定treeNode的多个数据项。

为了创建这个结构,我将calloc转换为treenode,将该treenode的地址传递给createListNode函数,并将calloc传递给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 个答案:

答案 0 :(得分:4)

不再需要时,应释放内存。这当然取决于您的应用程序的需求。

在垃圾收集环境(例如Java)中,垃圾收集器在没有任何指向它时释放内存。以此为出发点,您希望在删除对它的引用之前确保释放内存。

答案 1 :(得分:3)

最佳计划(IMO)是在您不再需要访问内存时释放内存。但是如果你只使用少量动态分配的内存,那么如果你在程序结束时完成所有操作,那么它可能不会产生太大的影响(假设你跟踪它的全部内容)

答案 2 :(得分:2)

很简单:

当您不再需要它时,您可以释放内存。在您的情况下,您似乎永远不必删除节点,因此不必担心删除任何节点。程序退出时会自动释放。但要小心,你应该删除所有引用它的指针超出范围的内存,使其无法使用。这可能会导致内存泄漏。

答案 3 :(得分:2)

当您不再需要从免费商店获得的资源时。因此,这取决于你没有使用 calloc 资源,你可以开始免费它。但要注意悬挂参考文献。

答案 4 :(得分:2)

您可以在不再需要时立即释放所有数据,例如在您完成打印后。在您的情况下,如果这是您编程的全部内容,则无关紧要,因为内核将在终止时释放程序分配的所有内存。但是,如果程序继续运行,这很重要,因为它意味着你吃了不能用于​​其他程序的内存。

这有点像以前版本的firefox,它在关闭标签后没有释放内存。该程序在不释放它的情况下不断要求更多的内存。

答案 5 :(得分:2)

你释放内存,一旦你不再使用它。如果在程序退出之前发生这种情况,你就可以在返回之前释放它。如果程序想要继续执行任何操作并且您不再需要树,则可以将其释放并继续执行该程序。

例如,如果树中的链接列表在某个阶段收缩,则应立即释放不再使用的节点。

答案 6 :(得分:0)

正如上面的每个人所说,当你不再需要它时,将其释放,但另外,尝试在你创建的同一级别上释放通常是一个好主意。当您传递引用等时,这会更复杂。