簡體   English   中英

在C ++中的刪除操作中出現段錯誤

[英]Seg fault in my delete operation in c++

我正在為C ++賦值編寫代碼,它是使用二進制搜索樹的字典實現。 我的代碼可以編譯,但是當我嘗試“刪除”時,出現段錯誤。 任何想法為什么會發生。 謝謝

這是我的代碼

// this function calls the deleteNode function where the deletion is done
void BST::deleteContent(string *word)
{
    deleteNode(word, root);
}
// a helper fuuntion for the deletecontent function
//uses recursion to find the node to be deleted
void BST::deleteNode(const string *word, Node *&nodePtr)
{
    if(word < nodePtr->word)
        deleteNode(word, nodePtr->left);
    else if(word > nodePtr->word)
        deleteNode(word, nodePtr->right);
    else
        makeDeletion(nodePtr);
}
// a helper function for the deleteNode function
void BST::makeDeletion(Node *&nodePtr)
{
    Node *tempNodePtr;

    if(nodePtr == NULL)
        cout<< "cannot delete empty node. \n";
    // if node has no right child
    else if (nodePtr->right == NULL)
        {
            tempNodePtr = nodePtr;
            nodePtr = nodePtr->left; // reattach child
            delete tempNodePtr;
        }
    else if(nodePtr-> left == NULL)
        {
            tempNodePtr = nodePtr;
            nodePtr = nodePtr->right; // reattach child
            delete tempNodePtr;
        }
    // if node has 2 children
    else
        {
            tempNodePtr = nodePtr->right;
            while (tempNodePtr->left)
                tempNodePtr = tempNodePtr->left;
            tempNodePtr->left = nodePtr->left;
            tempNodePtr = nodePtr;
            nodePtr = nodePtr->right;
            delete tempNodePtr;
        }
}

編輯

謝謝你們!! 從您的帖子中,我意識到檢查節點是否為最后一個節點並且沒有子節點是個好主意。 我在deleteNode中添加了此檢查

    if((nodePtr->left) && word < nodePtr->word)
    {
        do something
    }

我做了正確的工作,沒有拋出任何錯誤或段錯誤。 非常感謝!!!!

情況1:空樹:

假設您的樹為空: root將為nullptr 所以deleteContent()將調用deleteNode()與參數nullptrnodePtr

你在那里做的第一件事是比較wordnodePtr->word不先檢查nodePtrnullptr 這是您出現分割錯誤的第一種情況!

情況2:刪除不在樹中的單詞:

在這種情況下,將遞歸調用deleteNode()直到到達沒有后代的葉節點。 由於搜索到的單詞在樹中不存在,因此它的名稱比nodePtr-> word少,或者小於nodePtr-> word,但絕不相等。 deleteNode()然后將調用本身,再次通過論證nullptrnodePtr ,如情況1.同樣,你將有一個分割的錯!

情況1和2的解決方案:在deleteNode()中控制nullptr:

void BST::deleteNode(const string *word, Node *&nodePtr)
{
    if (nodePtr==nullptr) 
        cout << word << " not found in the tree\n";
    else if (word < nodePtr->word)
        ...   // the rest as in your original function 
}

makeDeletion()現在應該叫deleteNode()當且僅當nodePtr不是null word==nodePtr->word 擺脫第一個if()在任何情況下都不再為真。 可以用斷言at代替它以驗證不變量。

情況3:刪除樹中的單詞:

至少在我查看數據結構圖的情況下,所有這三種情況似乎都起作用(甚至具有兩個空指針的葉子節點)。

但是,我建議您驗證Node::~Node() temNodePtr Node::~Node() :在所有情況下,您都重新附加子節點,然后刪除舊節點( temNodePtr ),而無需將其子節點設置為nullptr 所以,我想知道是否~Node()只是破壞節點,而不考慮其照顧孩子(當時makeDeletion()應該工作),或者如果它是一個遞歸的析構函數,delete一個節點和它的孩子(當時makeDeletion()是行不通的,因為你會刪除您剛剛重新連接的節點,而不會引起注意,從而在第一次出現seg.fault)。

順便說一句,即使NULL也可以正常工作,對於指針,nullptr也許比NULL更合適。

暫無
暫無

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

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