简体   繁体   中英

Seg fault in my delete operation in c++

i am writing a code for a c++ assignment, it is a dictionary implementation using a binary search tree. My code compiles but when i try to "remove" i get a seg Fault. any ideas why did might be happening. Thanks

Here is my code

// 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;
        }
}

EDIT :

Thank you all!! From your post i realised it was a good idea to check if the node was the last and had no children. I added this check in deleteNode

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

i did the same for the right it worked and did not throw any errors or seg faults. Thanks so much!!!!

Case 1: Empty tree:

Suppose your your tree is empty: root will be nullptr . So deleteContent() will call deleteNode() with argument nullptr for nodePtr .

The first thing you do there is compare word with nodePtr->word without first checking that nodePtr is not nullptr . THere you have a first case of segmenation fault !

Case 2: Delete a word which is not in the tree:

In this case, deleteNode() will be called recursively until reaching a leaf node with no descendent. As the searched word does not exist in the tree, it's either geater or lesser than nodePtr->word, but never equal. deleteNode() will then call itself, again passing argument nullptr for nodePtr , as in case 1. Again you'll have a segmentation fault !

Solution to case 1 and 2: Control nullptr in deleteNode():

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() should now be called by deleteNode() if and only if nodePtr is not null and word==nodePtr->word . Get rid of the first if() which should no longer be true in any case. May be replace it with an assert at to verify the invariant.

Case 3: Delete a word in the tree :

All the three cases seem to work (even leaf nodes with two null pointers), at least if I look at my drawing of your data structure.

However I'd suggest to verify Node::~Node() : in all cases, you reattach the children and then you delete the old node ( temNodePtr ) without having set its children to nullptr . So I wonder whether ~Node() just destroys the node without taking care of its children (then makeDeletion() should work) or if its a recursive destructor, deleteing the node and its children (then makeDeletion() would not work because, you would delete the nodes that you've just reattached, without noticing it, thus creating a seg.fault at the first occasion).

By the way, nullptr would perhap's be be more appropriate than NULL for pointers, even if NULL would work properly as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM