2013-10-30 36 views
0

我正在編寫一個使用二叉樹數據結構的程序。當編寫例程以釋放所有節點時,我遇到了一個我無法解釋的特殊問題。使用二叉樹實現打印隨機數的內存自由函數

這是例程:

void destroy_tree(NodeT **tree){ 

    if(*tree != NULL){ 
     destroy_tree(&(*tree)->left); 
      free((*tree)->left); 
     destroy_tree(&(*tree)->right); 
      free((*tree)->right); 
    } 
    return; 
} 

基本上是一個2星級指針被傳遞給函數。它會在繼續釋放指針之前檢查每個節點是否爲NULL。 NodeT是一個包含NodeT結構的左和右指針的結構;這些是我試圖釋放的指針。

結構的定義爲:

typedef struct{ 
    int val; 
    struct tnode *right, *left; 
}NodeT; 

沒有免費的()調用什麼也沒有發生如你所願。然而,當免費撥打電話取消註釋輸出看起來是這樣的:

enter image description here

我每次運行程序的數量塊將改變,但它們始終與最終崩潰重複。

原來調用該函數是你所期望的是什麼,

destroy_tree(&rootNode); 

其中根節點爲:NodeT *rootNode;

任何想法?

+0

爲什麼你需要用雙指針來寫這個?單指針會更簡單。 –

+0

輸出從哪裏來?誰在印刷? –

+0

我同意 - 但這是一個項目,我們被要求實施2星級指針。這會更簡單。 – sherrellbc

回答

3

嘗試釋放,而不是當前節點:

void destroy_tree(NodeT **tree){ 

    if(*tree != NULL){ 
     destroy_tree(&(*tree)->left); 
     destroy_tree(&(*tree)->right); 
     free(*tree); 
    } 
    return; 
} 
+0

我會試試這個。 – sherrellbc

+0

這很好。我讓這變得更加困難。我釋放了兩個子節點,然後在返回給調用者時釋放父節點的子節點,它將成爲前一個當前節點。感謝您的建議。 – sherrellbc

1

你不說你正在運行什麼樣的系統,但我猜想,印刷從堆診斷程序抱怨堆來腐敗。

所以問題可能是你的樹實際上不是一棵樹 - NodeT在樹中出現兩次(所以它是一個DAG),或者更糟糕的是,其中一個指針指向一個父元素(有一個循環樹)。這些都會導致堆腐敗(未定義的行爲),這可能會導致任何事情發生。

我會建議使用valgrind或其他一些堆調試工具來運行以縮小一些問題,但是這仍然不會告訴你真正的問題在哪裏(哪些地方在創建樹的代碼中)。

+0

樹中的每個節點都是一個NodeT結構。我一直非常小心地把樹保持爲樹,但總有這種可能性。感謝您使用建議的軟件。 – sherrellbc