繁体   English   中英

C中的链接列表(内存问题)

[英]Linked List in C (memory problems)

我正在用C创建一个简单的链表,以习惯一些内存管理。 我定义了一个节点结构,该结构包含一个char *键,char *值和下一个node *。

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); 
} 

我在使用此删除功能时遇到问题。 从本质上讲,它似乎没有适当地删除键值节点,而是保留了节点的剩余部分,而不是完全删除它。 我不知道为什么这是可能的,尤其是当我将指针设置为指向需要删除的节点时。 在最坏的情况下,我觉得我应该只是在泄漏内存,但是当我打印出字典时,这些节点并不会以某种方式被删除,并且仍然是结构的一部分。 我是新来的,必须注意内存的布局,我看不到真正出了什么问题。

有什么建议么?

PS我的节点销毁功能是否没有正确释放内存?

可以立即说的是,如果您的键和值是字符串(根据您的代码,它们是字符串),那么要在内存中存储长度为N的字符串,您需要分配N + 1个字节,而不是N个字节。 零终止符字符需要额外的字节。 在您的代码中,将相应字符串的strlen s作为xy参数传递给分配函数,然后为键和值精确分配xy字符。 这已经是错误的。

您没有显示如何填写分配的键和值内存(可能是通过strcpy ),但是肯定会始终使分配的内存超出1个字节,从而造成灾难性的后果。

在C语言中,可以通过malloc()calloc()函数获取malloc() 有关更多详细信息,请访问http://scanftree.com/Data_Structure/linked-list

您永远不会从链接列表中删除已删除的节点。 它应该类似于(检查边缘情况):

current->next = current->next->next;

例如,如果您有:

{foo:bar} => {bar:baz} => {goo:gai}

而您要删除{bar:baz},则需要将foo的下一个指针设置为指向goo。 除非删除后current成为最后一个元素,否则您无需设置current->next

因此,释放的内存仍然存在于您的列表中,您稍后再阅读。 这是未定义的行为,但是如您所见,内存可能不会立即被重用。

一方面,您没有在字符串末尾为null分配空间。

另一个可能的问题是,您应确保初始化n->next = NULL

最后,

current = current->next->next;

应该

current->next = ...
current->next = malloc(sizeof(node));

应该是current-> next = calloc(1,sizeof(node)); / *因为-> next的安全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 */ 
}

当前->下一个= malloc(sizeof(node));

我假设你的意思是sizeof(node *)? 另外,我可以看到用于定义节点的结构吗? 还是整个程序?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM