简体   繁体   English

访问冲突在二叉搜索树中读取位置0x00000000

[英]Access violation reading location 0x00000000 in binary search tree

Just showing how the node of the binary tree looks like. 只显示二叉树的节点是什么样的。 I'm not sure what is wrong but I have a feeling it has something to do with the function being private. 我不确定有什么问题,但我觉得它与私有功能有关。 How I can compare the private data so I can see if the value I am looking for is inside that node? 我如何比较私有数据,以便我可以看到我正在寻找的值是否在该节点内?

    class binarytree
    {
    private:
        class node
        {
        public:

            int data;
            node * left;
            node * right;

            node (int x)
            {
                data = x;
                left=NULL;
                right=NULL;
            }


        };

    node * root;

This is how I insert the node 这是我插入节点的方式

    void insert(int x, node * &r)
        {
            if(r==NULL)
            {
                r= new node(x);
            }

            else
    {
        if(x < r->data)
        {
            //insert left
            insert(x, r->left);
        }

        else
        {
            //insert right
            insert(x, r->right);
        }
    }
}

Here is the part of the code that gives me trouble when I try to compare x to r->data the program crashes and gives me the error message " Access violation reading location 0x00000000" 以下是代码的一部分,当我尝试将x与r->数据进行比较时程序崩溃并给出错误消息“访问冲突读取位置0x00000000”时给我带来了麻烦

void remove(int x, node * &r)
{

    if(x == r->data)
    {
        if(r->right == NULL && r->left == NULL)
        {

            r = NULL;

        }

        else if(r->right == NULL && r->left != NULL)
        {
            r = r->left;

        }

        else if(r->right != NULL && r->left == NULL)
        {
            r = r->right;
        }

        else
        {
            node * temp;
            temp =r;
            r = r->left;
            while(r->right != NULL)
            {
                r = r->right;
            }

            r->right = temp->right;
            delete temp;
        }
    }

    else if ( x < r->data)
    {

        remove(x, r->left);

    }

    else if (x > r->data)
    {
        remove(x , r->left);
    }


}

This is where the functions are publicly. 这是功能公开的地方。 Then I call the private functions so I can manipulate the private tree. 然后我调用私有函数,以便我可以操作私有树。

public:

    binarytree()
    {
    root =  NULL;
    }

    ~binarytree()
    {
    //tooo: write this
    }

//return true if empty, false if not
    bool empty()
    {}


    void insert(int x)
    {
    insert(x, root);

    }




    void remove(int x)
    {
        remove(x,root);

    }

};

EDIT: Here is another function of the program that works but might be causing r to point to NULL. 编辑:这是该程序的另一个功能,但可能导致r指向NULL。

    int extractMin(node * &r)
{

    if(r->left == NULL)
    {
        if(r->right == NULL)
        {

            return r->data;

        }

        else
        {
            int x = r->data;
            r = r->right;
            return x;

        }
    }

    else
    {

        return extractMin(r->left);

    }
}

Here is the new function to check to see if r is NULL 这是检查r是否为NULL的新函数

    void remove(int x, node * &r)
{
    if(r == NULL)
    {
        cout<<"why am I null?"<<endl;
    }

    else
    {
        if(x == r->data)
        {
            if(r->right == NULL && r->left == NULL)
            {

                r = NULL;

            }

            else if(r->right == NULL && r->left != NULL)
            {
                r = r->left;

            }

            else if(r->right != NULL && r->left == NULL)
            {
                r = r->right;
            }

            else
            {
                node * temp;
                temp =r;
                r = r->left;
                while(r->right != NULL)
                {
                    r = r->right;
                }

                r->right = temp->right;
                delete temp;
            }
        }

        else if ( x < r->data)
        {

            remove(x, r->left);

        }

        else if (x > r->data)
        {
            remove(x , r->left);
        }

    }
}

you should always check for NULL before trying to get to the inner members: 在尝试访问内部成员之前,您应该始终检查NULL

void remove(int x, node * &r)
{
    if(r != NULL)
    {
       // Your code
    }
}

you call to remove with r as NULL and then try to check r.Left . 你调用以r删除为NULL然后尝试检查r.Left then here you have access violation 然后在这里你有访问冲突

also i must ask, did any if this worked for you? 我也必须问,如果这对你有用吗? specifically insert wont work this way. 特别insert不会这样工作。 try 尝试

    void insert(int x, node * &r)
    {
        if(r==NULL)
        {
            r= new node(x);
        }
        else
        {
            if(x < r->data)
            {
                if(r->left != NULL)
                {
                   //insert left
                   insert(x, r->left);
                }
                else
                {
                    r->left = new node(x);
                }
            }
            else
            {
                if(r->right != NULL)
                {
                   //insert right
                   insert(x, r->right);
                }
                else
                {
                    r->left = new node(x);
                }

            }
        }
    }

Well it the error says, r is pointing to NULL when you try to derefference it. 好吧,错误说,当你试图解除引用时,r指向NULL。 So you have to make sure when you assign memmory to r it doesn't return NULL. 所以你必须确保当你将memmory分配给r时它不会返回NULL。

binarytree()
{
    root =  NULL;
}

void remove(int x)
{
    remove(x,root);

}

In your case you are trying to derefference NULL (as the error says) This happens in your code when you are calling a remove before you have called an insert. 在您的情况下,您尝试解除引用NULL(如错误所示)当您在调用插入之前调用remove时,会在代码中发生这种情况。 You simply should check at the beginning of remove for r isn't pointing to NULL. 你应该在删除开始时检查r是不是指向NULL。 Or even better, make sure you won't parse in r when its NULL. 或者甚至更好,确保在其NULL时不会解析r。

r is null somehow. r以某种方式为空。 You need to check if the r passed in is NULL , or check if the root is non-null, and call remove on children only if they exist. 您需要检查传入的r是否为NULL ,或检查root是否为非null,并且仅在子项存在时调用remove

You are comparing x to the root . 您正在将xroot进行比较。 When your tree is empty, root == nullptr . 当您的树为空时, root == nullptr You should check to see if r == nullptr first, as in: 您应首先检查是否r == nullptr ,如:

bool remove(int x, node * &r) {
   if(!r) {
      return false; // Indicate whether removal succeeded
   }

   //... etc.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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