0

I have implemented a removeSelection function that removes a specific node from a leftist heap. The code locates the node via a hashtable that keeps track of the keys that have been inserted into the heap. The node is then percolated to the root of the heap and deleteMin is called to delete it. The code seems to be failing in the swapWithParent function that percolateUp calls and it generates a seg fault.

This is the function to be called from main on a heap:

    bool removeSelection( const Comparable & x )
{
    LeftistNode * temp = locateNode( x ); //find the node with the item
    if(temp == NULL)
        return false;
    //percolate that node to the top
    percolateUp(temp);
    //delete the root
    int derp = 0; //deleteMin requires an int be passed
    deleteMin(derp);
    return true;

}

The percolateUp function:

    void percolateUp( LeftistNode * t )
{
    if(t != NULL)
    {
        while(t != root)
        {
            t = swapWithParent(t->parent, t);
        }
    }
}

The swapWithParent function:

    //swap h2 with its parent h1
//return pointer to h2's new location
LeftistNode * swapWithParent(LeftistNode * h1, LeftistNode * h2)
{
    //if h2 is its parent's left child
    if(h2 == h1->left)
    {
        LeftistNode *temp = new LeftistNode(h2->element, -1, h1->parent, h1->left, h1->right, h1->npl); //clone h1 and store as a temp

        temp->lines = h2->lines;

        //update all pointers
        h1->parent = h2;
        if(h1->right != NULL)
            h1->right->parent = h2;
        h1->left = h2->left;
        h1->right = h2->right;
        h2 = temp;
        return h2;
    }
    else
    {
        LeftistNode *temp = new LeftistNode(h2->element, -1, h1->parent, h1->left, h1->right, h1->npl); //clone h1 and store as a temp
        temp->lines = h2->lines;
        //update all pointers
        h1->parent = h2;
        if(h1->left != NULL)
            h1->left->parent = h2;
        h1->left = h2->left;
        h1->right = h2->right;
        h2 = temp;
        return h2;

    }
}

Are there perhaps any places where I might be dereferencing a NULL pointer? I have checked, but I cannot seem to find the error.

Netsuki
  • 53
  • 9
  • `new` does not return a `NULL` in case of failure it throws an `std::bad_alloc` exception, Ofcourse unless you are compiling with exceptions disabled, for ex: In case of gcc, using `-fno-exceptions`. – Alok Save Mar 28 '12 at 04:20
  • I hope it's balanced by a fascist heap. Sorry. – Brett Hale Mar 28 '12 at 05:05

1 Answers1

0

If t->parent is NULL in the call t = swapWithParent(t->parent, t); then you will deference a NULL pointer in swapWithParent(). If parent is allowed to be NULL then add a check in swapWithParent() and if it shouldn't be NULL then at least add an assert() to ensure that it isn't being set to NULL erroneously.

uesp
  • 6,194
  • 20
  • 15
  • I changed the `percolateUp` function to include a check before the `swapWithParent` call. `if(t->parent != NULL) t = swapWithParent(t->parent, t);` However, I still receive a seg fault – Netsuki Mar 28 '12 at 05:18
  • I don't see any other obvious issue with the code. If the seg fault is due to memory corruption, however, the issue may be somewhere and is just becoming apparent at this point. You could try some logging or tracing through and look for strange/bad pointer value or contents. – uesp Mar 28 '12 at 12:40