2013-03-19 49 views
0
// So I call this function after deleting a node. 
// It works before I delete the node, but for some reason 
// after I perform a deletion and update the tree it runs into 
// EXC_BAD_ACCESS on the line below... 

void BinaryTree::updateCost(BinaryNode *root) { 
    if (root != NULL) 
     root->updateCostRecursively(1); 
} 

void BinaryNode::updateCostRecursively(int newCost) { 
    cout << this << endl; // prints 0x3000000000000000 before the bad access 
    cost = newCost; // has a bad access here 
    if (right != NULL) 
     right->updateCostRecursively(newCost + 1); 
    if (left != NULL) 
     left->updateCostRecursively(newCost + 1); 
} 

爲什麼在NULL對象上調用這個遞歸函數,即使每次都檢查指針?爲什麼在NULL檢查之後會在指針上調用遞歸函數?

我已經複製了我用來刪除下面節點的代碼。我仍然無法理解遞歸函數,但是從什麼時候我都可以告訴我離開一個懸掛的指針。

BinaryNode *BinaryTree::findMin(BinaryNode *t) { 
    if (t == NULL) return NULL; 
    while (t->left != NULL) t = t->left; 
    return t; 
} 

BinaryNode *BinaryTree::removeMin(BinaryNode *t) { 
    if (t == NULL) return NULL; 
    if (t->left != NULL) 
     t->left = removeMin(t->left); 
    else { 
     BinaryNode *node = t; 
     t = t->right; 
     delete node; 
    } 
    return t; 
} 

bool BinaryTree::remove(int key) { 
    if (root != NULL && remove(key, root)) 
     return true; 
    return false; 
} 

BinaryNode *BinaryTree::remove(int x, BinaryNode *t) { 
    if (t == NULL) return NULL; 

    if (x < t->key) 
     t->left = remove(x, t->left); 
    else if (x > t->key) 
     t->right = remove(x, t->right); 
    else if (t->left != NULL && t->right != NULL) { 
     // item x is found; t has two children 
     t->key = findMin(t->right)->key; 
     t->right = removeMin(t->right); 
    } else { //t has only one child 
     BinaryNode *node = t;  
     t = (t->left != NULL) ? t->left : t->right; 
     delete node; 
    } 

    updateCost(root); 
    return t; 
} 
+6

因爲它不是NULL?請注意'delete'不會修改指針。如果這不是問題,那麼請構建一個[最小測試用例](http://sscce.org)。 – 2013-03-19 22:16:35

+2

0x3000000000000000!= 0 – fbafelipe 2013-03-19 22:17:23

回答

1

錯誤發生在您的刪除方法中,而不是您發佈的代碼。刪除節點(例如root->right)後,需要設置root->right = NULL。你正在用delete做的事情是釋放指針指向的內存。指針本身繼續指向該地址。您正在嘗試訪問已釋放的內存,因此出現訪問異常錯誤。

+0

我粘貼了用於刪除節點的函數。從我所能告訴的我沒有留下一個晃來晃去的指針,但我可能是錯的。 – Yep 2013-03-19 22:23:01

+0

@Yep:我建議你用調試器仔細檢查你的'remove'函數,以確認這種或那種方式。 – 2013-03-19 22:43:10

+0

@Yep抱歉,我現在沒有時間仔細查看該代碼。一眼看來,如果你刪除一片葉子,你會看到一個懸掛指針。 – evanmcdonnal 2013-03-19 23:06:41

相關問題