C malloc valgrind - 在我的单链表实现中未初始化的内存

标签 c memory-leaks malloc valgrind singly-linked-list

我试图在c 中实现一个单向链表。我希望能够使用列表的多个实例,并且我想在主函数中创建列表。这就是为什么我选择以我的方式实现它。

代码工作得很好,但我担心是因为 valgrind 创建的输出。我还尝试在嵌入式系统的项目中使用代码,但出现了奇怪的错误。

valgrind 的输出是:

starting...

==3570== Conditional jump or move depends on uninitialised value(s)

==3570== at 0x100000E8E: push_cfront (in ./map_test)

==3570== by 0x100000D4F: main (in ./map_test)

==3570== Uninitialised value was created by a heap allocation

==3570== at 0x100008EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)

==3570== by 0x100000E80: push_cfront (in ./map_test)

==3570== by 0x100000D4F: main (in ./map_test)

==3570==

...finished

它还告诉我,我失去了一个街区。释放它哪里出错了

==3570== LEAK SUMMARY:

==3570== definitely lost: 16 bytes in 1 blocks

==3570== indirectly lost: 0 bytes in 0 blocks

==3570== possibly lost: 2,064 bytes in 1 blocks

==3570== still reachable: 0 bytes in 0 blocks

==3570== suppressed: 24,525 bytes in 186 blocks

请提示我哪里出错了。

测试.c:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "command_list.h"    
int main() {

    printf("starting...\n");

    Clist * command_list = malloc(sizeof(Clist));
    if (command_list == NULL) printf("Malloc Failed\n");
    command_list->head = NULL;

    //push_cback(command_list, 0);
    push_cfront(command_list,1);

    free_clist(command_list);
    free(command_list);
    printf("\n...finished\n");
    return 0;
}

命令列表.h:

#ifndef __COMMAND_LIST_H
#define __COMMAND_LIST_H

typedef struct cnode {
    uint8_t command;
    struct cnode * next;
} Cnode;

typedef struct clist {
    Cnode * head;
} Clist;

void push_cback(Clist * list, uint8_t command);
void push_cfront(Clist * list, uint8_t command);
void free_clist(Clist * list);

#endif

命令列表.c

void push_cfront(Clist * list, uint8_t command){
    Cnode * new_node;
    new_node = malloc(sizeof(Cnode));
    if (new_node->next == NULL) {
        return;
    }
    new_node->command = command;
    new_node->next = list->head;
    list->head = new_node;
}

void free_clist(Clist * list){
    if (list->head == NULL){
        return; //already empty
    }
    Cnode * current = list->head;
    while (current->next != NULL){
        Cnode* temp = current->next;
        free(current);
        current = temp;
    }
    free(current);
    list->head = NULL;
}

最佳答案

你有几个问题。您正在检查 new_node->next(malloc 内存中未初始化的数据)而不是 new_node(malloc 的返回值)。至少在我的计算机上,这也会导致内存无法释放,因为 new_node->next 偶然为 null,因此您返回时没有释放 new_node。另外,如果你想支持推到链表的后面,你应该考虑循环链表,因为它允许该操作而不必遍历整个链表。

最后,一些提示:您使用 valgrind 是件好事,但如果您使用 -g 编译以启用调试符号,这样 valgrind 会告诉您行号,这将更有帮助。此外,当我制作链表时,我喜欢对某些操作使用虚拟头节点,以避免出现空列表或单例列表的特殊情况。对于插入已排序的链表,该技术如下所示:

int sorted_insert(Clist *list, char new_command){
    Cnode _head = {NULL, list->head}, *head = &_head, *prev = head, *tmp;//head is an auto dummy node obviating null checks.
    int ord = -1;//If there are no existing nodes, newObj would be less than all objects.
    while(prev->next && (ord = (int)newObj - prev->next->command)) > 0){//Iterate by prev->next not curr to use only one pointer.
        prev = prev->next;//Looping while there is a next node and its data compares less than new_command.
    }
    if((!ord) || !(tmp = malloc(sizeof(Cnode))){//newObj is already in the list or allocation failed.
        return 0;
    }
    *tmp = (Cnode){.next=prev->next, .command=new_command};
    prev->next = tmp;
    list->head = head->next;//un- add head which is then deallocated by stack frame cleanup.
    return 1;
}

关于C malloc valgrind - 在我的单链表实现中未初始化的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38131541/

相关文章:

从 ImageMagick 安装 Mac 操作系统时 C 编译 fatal error 'file not found'

c - malloc 函数在 C 中如何工作?

C++ GDI+ 自己的类内存泄漏

c - 依次调用malloc和free函数是否会产生内存碎片?

C - 将缓冲区写入文件然后释放缓冲区会导致段错误

c - OpenMP 中的 Mandelbrot 集

c - 是否有返回 bool 的 C 库函数?

c# - UWP - 框架导航似乎会导致非托管内存泄漏

objective-c - objective-c :非空实例方法中的内存泄漏

c - malloc 问题?