什么时候应该释放动态分配的内存?
本质上,我创建了一段由树组成的代码,其中每个树节点都有自己的包含数据的链表(每个树节点也包含数据)。这样每个树节点可以有该特定树节点的多个数据项。
为了创建这个结构,我调用一个树节点,将该树节点的地址传递给 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;
}
}
}
Essentially, I have created a piece of Code which consists of a tree, whereby each tree node has its own linked list containing data, (each treeNode containing data as well). So that each treeNode can have multiple data items for that specific treeNode.
For this structure therefore to be created, I calloc a treenode, pass the address of that treenode to a createListNode function, and calloc a ListNode. My confusion stems really from, where exactly should I be freeing memory? Merely at the end of the program before return 0; in main, or elsewhere. Baring in mind once all the input is added to the tree and list, it then asks the user for a name, and displays the linked list of data appropriate for that name.
Cheers.
T.C.
EDIT:
#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;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
当您不再需要所有数据时,例如打印完毕后,您可以立即释放它们。就您而言,如果这就是您的程序所做的全部事情,那并不重要,因为您的内核将在终止时释放程序分配的所有内存。然而,如果程序继续运行,这很重要,因为这意味着您正在消耗无法用于其他程序的内存。
这有点像以前版本的 Firefox,关闭选项卡后不会释放内存。该程序不断请求越来越多的内存而不释放它。
You can free all the data as soon as you don't need it anymore, like when you're done printing it. In your case, if this is all what you program do it does not really matter as your kernel will free all memory allocated by your program at termination. However it matters if the program keeps running as it means you eating memory that cannot be used for other programs.
It's a bit like with previous version of firefox where it did not release memory after closing a tab. The program kept asking for more and more memory without releasing it.
正如上面每个人所说,当您不再需要它时将其释放,但此外,尝试在您创建的同一级别上释放它通常是一个好主意。当您传递引用等时,这会变得更加复杂。
As everyone above says, free it whe you don't need it anymore, but additionally it is often a good idea to try to free on the same level that you create. This is more complicated when you are passing references around and such.
当不再需要内存时,您应该释放它。这当然取决于您的应用程序的需求。
在垃圾收集环境(例如Java)中,当没有任何东西指向它时,垃圾收集器会释放内存。以此为起点,您需要确保在删除对内存的引用之前释放内存。
You should free the memory when it is no longer needed. That of course depends on your application's needs.
In garbage collected environments (e.g. Java) the garbage collector frees memory when nothing is pointing at it. Following that as a starting point, you want to be sure to free memory before you remove your references to it.
最好的计划(IMO)是在您不再需要访问内存时释放内存。但是,如果您只使用少量动态分配的内存,那么如果您在程序结束时执行所有操作(假设您跟踪所有内容),则可能不会产生太大影响
The best plan (IMO) is to free memory at the point where you don't need to access it any more. however if you only use a small amount of dynamically allocated memory it probably wont make much of a difference if you do it all at the end of your program (assuming you keep track of it all)
很简单:
当您不再需要内存时,可以释放它。就您而言,似乎您永远不必删除节点,因此不必担心删除任何节点。当你的程序退出时它会自动释放。但要小心,您应该删除所有引用它的指针超出范围的所有内存,使其无法使用。这可能会导致内存泄漏。
It's simple:
You free the memory when you have no more need for it. In your case, it seems you'll never have to remove a node so don't worry about deleting any. It is automatically freed when your program exits. Be careful though, you should delete all memory which all of its pointers that reference it get out of scope, making it unusable. This may cause memory leaks.
当您不再需要从免费商店获取的资源时。所以,这取决于你在什么时候不使用calloc资源,你可以开始释放它。但要小心悬空的引用。
When you no longer need the resources acquired from free store. So, it depends on what point you are not using calloc resources, you can start free it. But beware of dangling references.
一旦不再使用内存,就释放它。如果这种情况发生在程序退出之前,那么您可以在返回之前释放它。如果程序想继续执行任何操作,而您不再需要该树,则可以释放它并继续执行程序。
例如,如果树中的链表可能在某个阶段收缩,则应立即释放不再使用的节点。
You free the memory, once you have no use for it anymore. If that happens before program exit, well you free it before return. If the program wants to continue on whatever and you don't have need for the tree anymore, you free it and the continue with the program.
If for example the linked lists in the tree could at some stage shrink, the no-more-used nodes should be immediately freed.