2012-11-24 20 views
0

我想免費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); 
} 

我該如何解決這個問題?謝謝!

+3

我沒有看到任何地方將最後一個元素的' - > next'設置爲NULL。 – Mat

+0

這確實解決了這個問題,以及@alk提出的解決方案。謝謝你們 – user720491

+0

計算你的代碼執行的malloc數量。 –

回答

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; 

(背景對此,並不是所有的系統都需要這樣做y由NUL個字符(字節)的序列表示)。

無論如何,我不確定您是否將正確的東西指定爲next,因爲您沒有發佈list_elt的定義。


更新:

Regaring遞歸調用mtf_destroy()

雖然遞歸看起來很酷,而且確實是一個優雅的解決很多問題,使用起來往往容易出錯,對於因爲它們消耗系統資源(內存),所以在深入研究的情況下。

所以如果你的列表會很長,破壞它可能會破壞你的代碼。

我的建議:儘量不要遞歸,至少如果你不能預測事先要執行的遞歸級別。

+0

修復了症狀,但它在我看來仍然存在錯誤的錯誤。 –

相關問題