segment fault in some special unknown cases, driving me CRAZY

80 Views Asked by At

I've been debugging for a whole day and I really am completely lost. Help! I tested tons of cases locally in Visual Studio. It works fine. But on our school's online judge system, there are several cases reporting RE(exitcode 6) which means a segment fault problem. I really don't know what happened in these cases with all random cases working perfectly locally. I checked the list of possible problem s that may cause segment fault. I just cannot work it out, so please help. IT REALLY DRIVES ME CRAZY.

Note: It's a treap. There is a lot more code in the data structure but the rest works fine so I tried to pull all relevant code. I'm sure that the treapNode* treap::deleteNode(valueType value) function trigger the segment fault problem. If you notice anything missing though, please let me know.

I am really sorry it looks so long... any advice on my coding? I would really apprieciate that!

-------------------update----------------------

ok, I'll put all my code here to make it easier for you. BTW, I don't have access to a UNIX like platform...

-------------------update inputs format----------------

an example:

5         //the total number of the following operations
0 1 2     //this operation '0' means inserting '1' and '2' seperately
0 2 3     //while this means inserting '2' in x, '3' in y;
1 2 5     //skip operation '1'
2 0 1     //this operation '2' means delete the smallest number in x, and second small number in y
0 4 1

the oj promise not to insert the number that already exists and not to delete the rank that not exists.

#include <cstdio>
#include <ctime>
#include <cstdlib>
using namespace std;

typedef unsigned long long valueType;

struct treapNode
{
    valueType value;
    int prior;
    int lChildNum;
    int rChildNum;
    treapNode* lChild;
    treapNode* rChild;
    treapNode* parent;
    treapNode(valueType value, int randPrior)
    :value(value), prior(randPrior), lChildNum(0), rChildNum(0), lChild(NULL), rChild(NULL), parent(NULL) {}
};

class treap
{
public:
    treap(valueType value);
    treapNode* searchRank(treapNode* baseNode, valueType rank);
    treapNode* insertNode(valueType value);
    void deleteRank(valueType rank);
    void printTreap(treapNode* tempRoot);
    treapNode* root;
private:
    treapNode* searchValue(valueType value);
    treapNode* lRotate(treapNode* node);
    treapNode* rRotate(treapNode* node);
};

treap::treap(valueType value)
{
    srand(time(0));
    root = new treapNode(value, rand());
}

treapNode* treap::searchRank(treapNode* baseNode, valueType rank)
{
    baseNode = root;
    int delta;
    while (1)
    {
        delta = rank-baseNode->lChildNum-1;
        if (delta==0) break;
        if (delta>0) 
        {
            baseNode=baseNode->rChild;
            rank=delta;
        }
        else baseNode=baseNode->lChild;
    }

    return baseNode;
    // int delta=rank-baseNode->lChildNum-1;
    // if (delta==0) return baseNode;
    // if (delta>0)
    // {
    //     //baseNode must have a rChild
    //     return searchRank(baseNode->rChild, delta);
    // }
    // else
    // {
    //     //baseNode must have a lChild
    //     return searchRank(baseNode->lChild, rank);
    // }
}

treapNode* treap::searchValue(valueType value)
{
    treapNode* travNode = root;
    while (1)
    {
        if (value>travNode->value)
        {
            if (travNode->rChild==NULL) break;
            travNode=travNode->rChild;
        }
        if (value<travNode->value)
        {
            if (travNode->lChild==NULL) break;
            travNode=travNode->lChild;
        }
    }

    return travNode;
}

void treap::deleteRank(valueType rank)
{
    treapNode* deleteRankPointer = searchRank(root, rank);
    treapNode* tempNodePointer=deleteRankPointer;
    while(1)
    {
        if (tempNodePointer->lChild!=NULL || tempNodePointer->rChild!=NULL)
        {
            if (tempNodePointer->lChild!=NULL && (tempNodePointer->rChild==NULL || tempNodePointer->lChild->prior>tempNodePointer->rChild->prior)) rRotate(tempNodePointer);
            else lRotate(tempNodePointer);
        }
        else
        {
            if (tempNodePointer->parent->value>tempNodePointer->value)
            {
                tempNodePointer=tempNodePointer->parent;
                tempNodePointer->lChild=NULL;
                tempNodePointer->lChildNum=0;
                deleteRankPointer->parent=NULL;
                delete deleteRankPointer;
            }
            else
            {
                tempNodePointer=tempNodePointer->parent;
                tempNodePointer->rChild=NULL;
                tempNodePointer->rChildNum=0;
                deleteRankPointer->parent=NULL;
                delete deleteRankPointer;
            }
            break;
        }
    }
    treapNode* travNode=tempNodePointer;
    while (travNode!=root)
    {
        if (travNode->parent->value>travNode->value) travNode->parent->lChildNum--;
        else travNode->parent->rChildNum--;
        travNode=travNode->parent;
    }
}

treapNode* treap::insertNode(valueType value)
{
    treapNode* tempNodePointer = searchValue(value);
    if (tempNodePointer->value>value) 
    {
        //tempNodePointer->lChildNum++;
        tempNodePointer->lChild=new treapNode(value, rand());
        tempNodePointer->lChild->parent=tempNodePointer;
        tempNodePointer=tempNodePointer->lChild;
    }
    else 
    {
        //tempNodePointer->rChildNum++;
        tempNodePointer->rChild=new treapNode(value, rand());
        tempNodePointer->rChild->parent=tempNodePointer;
        tempNodePointer=tempNodePointer->rChild;
    }
    treapNode* travNode = tempNodePointer;
    //update by prior first
    while (travNode!=root)
    {
        if (travNode->prior<=travNode->parent->prior) break;
        if (travNode->parent->value>travNode->value) rRotate(travNode->parent);
        else lRotate(travNode->parent);
    }
    //update the childNum of upper nodes
    while (travNode!=root)
    {
        if (travNode->parent->value>travNode->value) travNode->parent->lChildNum++;
        else travNode->parent->rChildNum++;
        travNode=travNode->parent;
    }

    return tempNodePointer;
}

treapNode* treap::lRotate(treapNode* node)
{
    //node has a rChild

    if (node!=root)
    {
        //node has a parent
        if (node->parent->value>node->value) node->parent->lChild=node->rChild;
        else node->parent->rChild=node->rChild;
        node->rChild->parent=node->parent;
    }
    else
    {
        root=root->rChild;
        root->parent=NULL;
        //no need to update childNum
    }
    treapNode* tempNodePointer = node->rChild;
    if (node->rChild->lChild!=NULL)
    {
        node->rChild=node->rChild->lChild;
        node->rChildNum=tempNodePointer->lChildNum;
        node->rChild->parent=node;
    }
    else 
    {
        node->rChild=NULL;
        node->rChildNum=0;
    }
    tempNodePointer->lChild=node;
    node->parent=tempNodePointer;
    tempNodePointer->lChildNum=node->lChildNum+node->rChildNum+1;

    return tempNodePointer;
}

treapNode* treap::rRotate(treapNode* node)
{
    //node has a lChild

    if (node!=root)
    {
        //node has a parent
        if (node->parent->value>node->value) node->parent->lChild=node->lChild;
        else node->parent->rChild=node->lChild;
        node->lChild->parent=node->parent;
    }
    else
    {
        root=root->lChild;
        root->parent=NULL;
        //no need to update childNum
    }
    treapNode* tempNodePointer = node->lChild;
    if (node->lChild->rChild!=NULL)
    {
        node->lChild=node->lChild->rChild;
        node->lChildNum=tempNodePointer->rChildNum;
        node->lChild->parent=node;
    }
    else 
    {
        node->lChild=NULL;
        node->lChildNum=0;
    }
    tempNodePointer->rChild=node;
    node->parent=tempNodePointer;
    tempNodePointer->rChildNum=node->lChildNum+node->rChildNum+1;

    return tempNodePointer;
}

void treap::printTreap(treapNode* tempRoot)
{
    if (tempRoot->lChild!=NULL) printTreap(tempRoot->lChild);
    printf("%lld: %d; lN: %d; rN: %d; lC: %lld; rC: %lld\n", tempRoot->value, tempRoot->prior, tempRoot->lChildNum, tempRoot->rChildNum, tempRoot->lChild==NULL?0:tempRoot->lChild->value, tempRoot->rChild==NULL?0:tempRoot->rChild->value);
    if (tempRoot->rChild!=NULL) printTreap(tempRoot->rChild);
}

int main()
{
    int n;
    scanf("%d", &n);

    int op;
    valueType inputX, inputY;
    int result=0;

    scanf("%d %lld %lld", &op, &inputX, &inputY);

    treap* xTreap=new treap(inputX);
    treap* yTreap=new treap(inputY);

    int Count=1;
    for (int i=1; i<n; i++) 
    {
        scanf("%d %lld %lld", &op, &inputX, &inputY);
        switch (op)
        {
            case 0:
                xTreap->insertNode(inputX);
                yTreap->insertNode(inputY);
                Count++;
                break;
            case 1:
                break;
            case 2:
                xTreap->deleteRank(inputX+1);
                yTreap->deleteRank(inputY+1);
                Count--;
                break;
            default:
                break;
        }
    }

    return 0;
}
0

There are 0 best solutions below