簡體   English   中英

BST的段故障remove()函數

[英]Seg-Fault at BST remove() Function

基本上,該程序由BST類組成,該類指向二叉樹的第一個節點,並且這些節點也是它們自己的類。

BST調用此成員函數:

void remove(const T& x)
{
    removeNode(m_root, x);
    return;
}

這是remove節點的遞歸部分,運行到完成:

template <typename T>
void removeNode(TreeNode<T>* &p, const T& x)
{
    if(p == NULL)
        return;

    if(x < p -> m_data)
        removeNode(p -> m_left, x);
    else if(x > p -> m_data)
        removeNode(p -> m_right, x);

    else
    {
        TreeNode<T>* tmp = new TreeNode<T>;

        if(p -> m_left == NULL)
        {
            tmp = p -> m_right;
            delete p;
            p = tmp;
        }
        else if(p -> m_right == NULL)
        {
            tmp = p -> m_left;
            delete p;
            p = tmp;
        }
        else
        {
            tmp = p -> m_right;
            TreeNode<T>* tmp2 = new TreeNode<T>;

            while(tmp -> m_left != NULL)
            {
                tmp2 = tmp;
                tmp = tmp -> m_left;
            }

            p -> m_data = tmp -> m_data;

            if(tmp2 != NULL)
                removeNode(tmp2 -> m_left, tmp -> m_left -> m_data);
            else
                removeNode(p -> m_right, p -> m_right -> m_data);
        }
    }

    return;
}

我在remove()函數返回時出現段錯誤,我想知道為什么?

用戶@WhozCraig指出了代碼中最重要的錯誤:您分配了永不使用(永不銷毀!)的對象:

TreeNode<T>* tmp = new TreeNode<T>;

TreeNode<T>* tmp2 = new TreeNode<T>;

后一個分配導致條件

if(tmp2 != NULL)

永遠滿意,這會阻止您執行

else
    removeNode(p -> m_right, ...)

科。

編輯

假設您有一個包含2個,5個和7個鍵的三節點樹。讓我們分別表示節點node2node5node7 假設node5是樹根。 假設您還要卸下鑰匙5。
然后:

  • *p == node5 ;
  • if不滿足s,則前三個,控制權傳遞給else分支;
  • tmp分配給p->m_right ,即&node7
  • tmp2被分配了一個新的“空”對象-我們稱它為nodeEmpty
  • node7沒有子tmp->m_left ,因此tmp->m_leftNULL ,並且while循環被跳過,沒有迭代;
  • 分配指令p->m_data = tmp->m_data使node5獲得密鑰7;
  • 作為tmp2 == &nodeEmpty不為NULL ,您調用
    • removeNode(tmp2 -> m_left, tmp -> m_left -> m_data)

這顯然將要從nodeEmptynodeEmpty )的不存在的左子樹中刪除某些內容, 但是...
但是,此時tmp == &node7 ,而node7沒有子級,因此tmp->m_left == NULL 因此,訪問tmp->m_left->m_data會觸發內存訪問錯誤,並且在遞歸調用removeNode之前,進程會崩潰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM