2014-09-21 26 views
-2

我似乎無法爲我的生活弄清楚我的代碼在刪除整個BST時出了什麼問題。C - 刪除整個BST時出錯

我的身影,因爲似乎沒有成爲一個問題與此:

void emptyTree(BST **root){ 
    if((*root)!=NULL){ 
     emptyTree(&(*root)->left); 
     emptyTree(&(*root)->right); 
     free(*root); 
    } 
} 

那麼整個問題在於每個節點的樹的初始入口。任何人都可以指出這裏有什麼問題嗎?

void insertNode(BST **root, BST *temp){ 
    if((*root)!=NULL){ 
     temp->parent = *root; 
     if(((*root)->value) < (temp->value))  
      insertNode(&(*root)->right,temp); 
     else if(((*root)->value) > (temp->value)) 
      insertNode(&(*root)->left,temp); 
     else if(((*root)->value) == (temp->value)){ 
      printf("The number %i is already in the tree.\n",temp->value); 
      return; 
     } 
    } else { 
     *root = temp; 
     printf("%i was added to the tree.\n",temp->value); 
     return; 
    } 
} 

void newNode(BST **root, int x){ 
    BST *newnode; 

    newnode = (BST *)malloc(sizeof(BST)); 
    newnode->value = x; 
    newnode->left = newnode->right = newnode->parent = NULL; 

    insertNode(root,newnode); 
} 

它編譯運行它絕對是對每個函數的權利(包括一次刪除一個節點的權利)。除「全部刪除」(emptyTree)之外。它不會刪除所有內容(?)。當我運行emptyTree函數時,它甚至不會顯示錯誤。它只有當我打印整棵樹時纔會出錯。

+1

那麼,有一件事可能是[在C中,你不應該投入返回或'malloc'](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc )。 – 2014-09-21 11:03:33

+2

您需要逐步調試調試器中的代碼,以查看發生了什麼 - 這比通過查看代碼(或者要求其他人執行相同操作)來猜測出現問題更有成效。 – 2014-09-21 11:04:04

+3

你說有什麼不對。你怎麼知道?它是否編譯?跑?刪除文件呢? – usr2564301 2014-09-21 11:04:59

回答

2

發生此錯誤的原因是您的做了釋放所有數據,但忘記指示您的元素不再包含有效數據。
也就是說,在刪除之後,所有元素的leftright成員以及您自己的root本身仍包含a值;它們仍包含原始值,但這些不再指向有效的,已分配的內存。

該錯誤並不直接發生在emptyTree之內,因爲這從終端節點一直運行到頂部,並且沒有理由檢查「關閉」。但只要您嘗試打印root(及其後代),您正在訪問未分配的內存。

插入

*root = NULL; 
emptyTree功能

free(*root); 

後把它emptyTree函數內部,或致電emptyTree後置root爲NULL。

就我個人而言,我更喜歡前者,即使它是一個小的開銷。這樣,你只有一個函數來刪除一棵樹,而不是遞歸的,還有一個包裝器,它也將根設置爲NULL。

+0

我發佈了這個問題後寫了* root = NULL,但是我不確定它是否實際解除分配,或者它只是鏈接到NULL,從而失去了整個樹。謝謝你的清晰度:) – 2014-09-21 12:59:02

+0

是的,你需要兩個。 'free(x)'將指向的內存標記爲* free *,但對'x'沒有任何影響。 'x = NULL;'相反; *你*說你不再需要指針,但內存塊保持分配狀態,不能以任何方式釋放。 – usr2564301 2014-09-21 13:10:09