条件跳转或移动取决于未初始化的值 - 释放链表

时间:2012-11-24 10:41:03

标签: c linked-list free valgrind

我想在C中释放链接列表。一切正常,但Valgrind告诉我

Conditional jump or move depends on uninitialised value(s)
    at 0x401400: mtf_destroy

以下是代码:

list_elt *head;

void mtf_init() {
    list_elt *current;
    head = malloc(sizeof(list_elt));
    current = head;
    for (int i = 0; i < LIST_SIZE-1; i++) {
        current->value = (BYTE) i;
        current->next = malloc(sizeof(list_elt));
        current = current->next;
    }
    current->value = LIST_SIZE-1;
}

void mtf_destroy(list_elt *elt) {
    if (elt->next != NULL)
        mtf_destroy(elt->next);
    free(elt);
}

我该如何解决这个问题?谢谢!

1 个答案:

答案 0 :(得分:4)

Valgrind想告诉你elt->next用作if()的表达式的实例尚未初始化,因此if()做出的决定是随机的。

您可能想要更改:

head = malloc(sizeof(list_elt));
...
  current->next = malloc(sizeof(list_elt));

是:

head = calloc(1, sizeof(list_elt));

..."
  current->next = calloc(1, sizeof(list_elt));

一种可移植的方法是使用NULL显式初始化所有指针:

head = calloc(1. sizeof(list_elt));
head->next = NULL;
...
  current->next = calloc(1, sizeof(list_elt));
  current->next->next = NULL;

(背景是,并非在所有系统上NULL - 指针必须由NUL个字符(字节)序列表示。

无论如何,我不确定你是否将正确的内容分配给next,因为你没有发布list_elt的定义。


<强>更新

重新调用mtf_destroy()的递归调用:

尽管递归看起来很酷,并且确实是许多问题的优雅解决方案,但使用它们往往容易出错,例如在进入非常深的情况下,因为它们消耗系统资源(内存)。

因此,如果您的列表真的很长,那么销毁它可能会破坏您的代码。

我的建议:尝试在没有递归的情况下进行,至少如果你无法提前预测递归水平。