本质上,我创建了一段由树组成的代码,每个树节点都有自己的包含数据的链表(每个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;
}
}
}
答案 0 :(得分:4)
不再需要时,应释放内存。这当然取决于您的应用程序的需求。
在垃圾收集环境(例如Java)中,垃圾收集器在没有任何指向它时释放内存。以此为出发点,您希望在删除对它的引用之前确保释放内存。
答案 1 :(得分:3)
最佳计划(IMO)是在您不再需要访问内存时释放内存。但是如果你只使用少量动态分配的内存,那么如果你在程序结束时完成所有操作,那么它可能不会产生太大的影响(假设你跟踪它的全部内容)
答案 2 :(得分:2)
很简单:
当您不再需要它时,您可以释放内存。在您的情况下,您似乎永远不必删除节点,因此不必担心删除任何节点。程序退出时会自动释放。但要小心,你应该删除所有引用它的指针超出范围的内存,使其无法使用。这可能会导致内存泄漏。
答案 3 :(得分:2)
当您不再需要从免费商店获得的资源时。因此,这取决于你没有使用 calloc 资源,你可以开始免费它。但要注意悬挂参考文献。
答案 4 :(得分:2)
您可以在不再需要时立即释放所有数据,例如在您完成打印后。在您的情况下,如果这是您编程的全部内容,则无关紧要,因为内核将在终止时释放程序分配的所有内存。但是,如果程序继续运行,这很重要,因为它意味着你吃了不能用于其他程序的内存。
这有点像以前版本的firefox,它在关闭标签后没有释放内存。该程序在不释放它的情况下不断要求更多的内存。
答案 5 :(得分:2)
你释放内存,一旦你不再使用它。如果在程序退出之前发生这种情况,你就可以在返回之前释放它。如果程序想要继续执行任何操作并且您不再需要树,则可以将其释放并继续执行该程序。
例如,如果树中的链接列表在某个阶段收缩,则应立即释放不再使用的节点。
答案 6 :(得分:0)
正如上面的每个人所说,当你不再需要它时,将其释放,但另外,尝试在你创建的同一级别上释放通常是一个好主意。当您传递引用等时,这会更复杂。