未初始化的内存在我的单链表实现中

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

代码工作得很好,但由于输出valgrind创建,我很担心。 此外,我尝试在嵌入式系统的项目中使用代码,并发生奇怪的错误。

valgrind输出是:

开始...

== 3570 ==条件跳转或移动取决于未初始化的值(s)

== 3570 == 0x100000E8E:push_cfront(在./map_test中)

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

== 3570 ==未初始化的值是由堆分配创建的

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

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

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

== == 3570

...完成

它也告诉我,我失去了一个街区。 我在哪里解决它的错误

== 3570 ==泄漏摘要:

== 3570 ==绝对丢失:1个块中的16个字节

== 3570 ==间接丢失:0个字节0个字节

== 3570 ==可能丢失:1块中2,064个字节

== 3570 ==仍然可以访问:0个字节的0个字节

== 3570 ==抑制:186块中的24,525字节

请给我一个提示我出错的地方。

test.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 Failedn");
    command_list->head = NULL;

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

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

command_list.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

command_list.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->nextnew_node->next内存中的未初始化数据)而不是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;
}

当你检查它的值时, new_node->next是未初始化的。 你不需要那个。

如果您查找malloc失败,请为malloc设置返回码并在调用时检查它。

在此之前,不需要push_cfrontif分支。

...或者你想检查list->head而不是?


此外, push_cfront这段代码也有问题

new_node = malloc(sizeof(Cnode));
if (new_node->next == NULL) {
    return;
}

由于new_node内存未初始化,因此它是未定义的行为。 您可能想检查if (new_node == NULL)查看内存是否实际分配。

链接地址: http://www.djcxy.com/p/64951.html

上一篇: uninitialised memory in my singly linked list implementation

下一篇: Suppression file too general?