2

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

因此,为了创建这个结构,我调用一个树节点,将该树节点的地址传递给一个 createListNode 函数,然后调用一个 ListNode。我的困惑真正源于,我究竟应该在哪里释放内存?仅在程序结束前返回 0;在主要或其他地方。记住,一旦将所有输入添加到树和列表中,它就会向用户询问名称,并显示适合该名称的数据链接列表。

干杯。

TC

编辑:

#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;
    }
}
}
4

7 回答 7

4

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

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

于 2011-11-28T23:38:53.400 回答
3

最好的计划(IMO)是在您不再需要访问它的地方释放内存。但是,如果您只使用少量动态分配的内存,那么如果您在程序结束时执行所有操作(假设您跟踪所有内容),可能不会有太大的不同

于 2011-11-28T23:38:06.497 回答
2

这很简单:

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

于 2011-11-28T23:38:19.267 回答
2

当您不再需要从免费商店获得的资源时。所以,这取决于你什么时候没有使用calloc资源,你可以开始释放它。但要注意悬空引用。

于 2011-11-28T23:38:21.370 回答
2

您可以在不再需要时立即释放所有数据,例如完成打印后。在您的情况下,如果这就是您程序所做的全部,那并不重要,因为您的内核将在终止时释放程序分配的所有内存。但是,程序是否继续运行很重要,因为这意味着您正在消耗无法用于其他程序的内存。

这有点像以前版本的 Firefox,它在关闭选项卡后没有释放内存。该程序不断要求越来越多的内存而没有释放它。

于 2011-11-28T23:38:57.930 回答
2

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

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

于 2011-11-28T23:39:24.753 回答
0

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

于 2011-11-29T23:03:17.060 回答