C链表内存泄漏

标签 c memory-leaks linked-list

我想不通为什么我的链表有内存泄漏。

我有一个名为 insertAtFront() 的方法

void insertAtFront(Node **head, char *key) {
    Node *new =  malloc(sizeof(Node));
    if (!new)  fatal("Malloc of new Node failed");
    new->word = key;
    new->next = *head;
    *head = new;
}

然后我有一个释放节点的 removeAtFront() 方法。

void removeAtFront(Node **head) { 
    Node *newhead = (*head)->next;
    free(*head);
    *head = newhead;
}

如果我只添加一个节点然后将其删除,则不会发生泄漏。如果我删除了多个节点,valgrind 会显示与添加的额外节点数量成比例的泄漏。我真的不明白为什么在释放节点时会发生这种情况。有什么想法吗?

最佳答案

您的问题似乎是生命周期问题。您没有发布调用代码和完整的可验证示例。节点已正确释放,但有些地方没有。 key 参数是否已分配但未在其他地方释放?

当您释放节点时,您不会释放 word 成员。如果 key 参数是由调用 insertAtFront() 的函数分配的,它应该随节点一起释放。如果 word 字段仅在某些时候被分配,则很难确定何时释放它。

一个好的解决方案是 insertAtFont() 总是复制 key 字符串,而 removeAtFront() 总是释放 单词成员:

void insertAtFront(Node **head, const char *key) {
    Node *new =  malloc(sizeof(*new));
    if (!new)  fatal("Malloc of new Node failed");
    new->word = strdup(key);
    if (!new->word)  fatal("Malloc of Node key failed");
    new->next = *head;
    *head = new;
}

void removeAtFront(Node **head) {
    Node *node = *head;
    if (node) { 
        *head = node->next;
        free(node->word);
        free(node);
    }
}

请注意,insertAtFront() 可以方便地免费返回指向新插入节点的指针。

关于C链表内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35420629/

相关文章:

无法构建 C 程序

c - 三角形未在 GLFW3 中渲染

C动态分配内存块

java - 如何在喜欢列表中任意插入节点?

c - 为什么 WSAConnect 可以工作并且 connect();不是?

c - open() 系统调用中的第三个参数如何工作?

variables - 声明变量内存泄漏

c++ - 在 Visual Studio 单元测试中检查内存泄漏

java - Weblogic,SUN,Apache和Oracle类中的内存泄漏问题

c++ - 这个链表是如何流动的?