我在C中创建一个简单的链表,以便习惯一些内存管理。我已经定义了一个节点结构,它包含一个char *键,一个char *值和一个节点* next。
void newnode(node *n, int x, int y)
{
n->key = malloc(x*sizeof(char));
n->value = malloc(y*sizeof(char));
}
//This how i create a new node given a key and value to make sure that I have allocated the proper amount of space. x and y are the strlengths of the key and value being added.
// In the add function I use the following two lines (when it is valid to add a new key value pair)
current->next = malloc(sizeof(node));
node_newnode(current->next,strlen(key),strlen(value));
// My remove function then searches for a key and if that key exists in the structure it removes that node. I use a delete point to keep track of the node needing deletion.
void remove(dict *d, const char *key)
{
node* delete;
node* current;
current = d->head;
while(current->next != NULL){
if(strcmp(current->next->key,key)==0){
delete = current->next;
if(current->next->next != NULL)
current = current->next->next;
else
current->next = NULL;
node_destroy(delete);
break;
}
current = current->next;
}
}
// Here is the node_destroy function I used in remove.
void node_destroy(node* delete)
{
free(delete->key);
free(delete->value);
free(delete);
}
我遇到了这个删除功能的问题。从本质上讲,它似乎没有正确删除键值节点,而是留下节点的残余而不是完全删除它。我不知道为什么这是可能的,特别是当我设置指针指向需要删除的节点时。在最坏的情况下,我觉得我应该只是泄漏内存,但不知何故这些节点没有被删除,并且当我打印出字典时仍然是结构的一部分。我不得不关注内存的布局,我真的不知道什么是错的。
有什么建议吗?
P.S。我的节点销毁功能是否没有正确释放内存?
答案 0 :(得分:3)
可以立即说的是,如果您的键和值是字符串(并且它们是根据您的代码),那么要在内存中存储长度为N的字符串,您需要分配N + 1个字节,而不是N字节。零终结符字符需要额外的字节。在您的代码中,您将相应字符串的strlen
作为x
和y
参数传递给分配函数,然后为x
和y
字符准确分配关键和价值。这已经错了。
您没有显示如何填写分配的键和值内存(可能是strcpy
),但它肯定会将分配的内存一直超出1个字节而带来灾难性的后果。
在C语言中,可以通过malloc()
和calloc()
函数获取内存。
有关详细信息,请访问http://scanftree.com/Data_Structure/linked-list
答案 1 :(得分:1)
您永远不会从链接列表中删除已删除的节点。它应该是(检查边缘情况):
current->next = current->next->next;
E.g。如果你有:
{foo:bar} => {bar:baz} => {咕:盖}
你要删除{bar:baz},你需要设置foo的下一个指针指向goo。除非删除current->next
成为最后一个元素,否则您不会设置current
。
因此,释放的内存仍然存在于列表中,您稍后会阅读它。这是未定义的行为,但正如您所看到的,内存可能无法立即重用。
答案 2 :(得分:0)
首先,你没有在字符串末尾为空值分配空间......
另一个可能的问题是,您应该确保初始化n->next = NULL
;
最后,
current = current->next->next;
应该是
current->next = ...
答案 3 :(得分:0)
current->next = malloc(sizeof(node));
应该是 current-> next = calloc(1,sizeof(node)); / *因为安全NULL测试 - >下一个! * /
void newnode(node *n, int x, int y)
{
n->key = malloc(x*sizeof(char));
n->value = malloc(y*sizeof(char));
}
应该是
void newnode(node *n, int x, int y)
{
n->key = malloc(x+1); /* because x comes from strlen() and sizeof(char)==1 */
n->value = malloc(y+1); /* because x comes from strlen() and sizeof(char)==1 */
}
答案 4 :(得分:-3)
current-> next = malloc(sizeof(node));
我假设你的意思是sizeof(node *)?另外,我可以看到用于定义节点的结构吗?或许整个计划?