C++ 二元搜索树中的访问冲突读取位置0x00000000

C++ 二元搜索树中的访问冲突读取位置0x00000000,c++,access-violation,C++,Access Violation,只是显示二叉树的节点是什么样子。我不确定是什么问题,但我有一种感觉,这与函数的私密性有关。如何比较私有数据,以便查看我要查找的值是否在该节点内 class binarytree { private: class node { public: int data; node * left; node * right; node (

只是显示二叉树的节点是什么样子。我不确定是什么问题,但我有一种感觉,这与函数的私密性有关。如何比较私有数据,以便查看我要查找的值是否在该节点内

    class binarytree
    {
    private:
        class node
        {
        public:

            int data;
            node * left;
            node * right;

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


        };

    node * root;
这就是插入节点的方式

    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);
        }
    }
}
编辑:这是程序的另一个功能,它可以工作,但可能会导致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);

    }
}
下面是检查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);
        }

    }
}
void删除(int x,node*&r)
{
if(r==NULL)
{
coutright==NULL&&r->left!=NULL)
{
r=r->左;
}
如果(r->right!=NULL&&r->left==NULL),则为else
{
r=r->右;
}
其他的
{
节点*温度;
温度=r;
r=r->左;
while(r->right!=NULL)
{
r=r->右;
}
r->右侧=临时->右侧;
删除临时文件;
}
}
else if(xdata)
{
移除(x,r->左侧);
}
否则如果(x>r->数据)
{
移除(x,r->左侧);
}
}
}

如果错误是这样说的,那么当您尝试去区分它时,r指向NULL。 因此,您必须确保当您将memmory分配给r时,它不会返回NULL

binarytree()
{
    root =  NULL;
}

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

}
在您的例子中,当您在调用insert之前调用remove时,您试图取消差异NULL(正如错误所说的那样),这种情况会在代码中发生。 您只需在remove的开头检查r是否指向NULL。
或者更好的方法是,确保在r为NULL时不会在r中进行解析。

在尝试访问内部成员之前,应始终检查
NULL

void remove(int x, node * &r)
{
    if(r != NULL)
    {
       // Your code
    }
}
您可以使用
r
作为
NULL
调用remove,然后尝试选中
r.Left
。那么这里就有访问冲突了

我还要问,这对你有用吗?具体来说,
insert
不会以这种方式工作。 试一试

void插入(int x,node*&r)
{
if(r==NULL)
{
r=新节点(x);
}
其他的
{
如果(x数据)
{
如果(r->left!=NULL)
{
//向左插入
插入(x,r->左);
}
其他的
{
r->左=新节点(x);
}
}
其他的
{
如果(r->右!=空)
{
//插入右侧
插入(x,r->右侧);
}
其他的
{
r->左=新节点(x);
}
}
}
}

r
以某种方式为空。您需要检查传入的
r
是否为
NULL
,或者检查
root
是否为非NULL,并且仅当子项存在时才调用
remove

您正在将
x
root
进行比较。当树为空时,
root==nullptr
。您应该首先检查
r==nullptr
,如下所示:

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

   //... etc.
}

TL;DR(见附件)。无论如何,“访问冲突读取位置0x00000000”显然是一个空指针取消引用。请在调试器中运行程序,逐行检查
insert
函数,以确保其正常工作。如果是,则逐行执行
remove
函数。似乎在
remove
函数中,您需要检查
r
是否为
NULL
。。。如果它是。。。正如Joachim所说,当你遇到这种问题时,使用一个调试器。好的,我检查了NULL,它显示r==NULL。我的根如何为NULL?@user2782774正如我在回答中告诉你的:你在构造函数中将它设置为NULL,因此如果你在调用isnert之前调用remove,你就没有更改它。或者,如果您在没有节点的情况下调用remove,那么您也会将其设置为NULL,这可能是因为错误的循环索引或其他原因。。。你甚至不知道你自己的代码吗?@user2782774另外,我认为你的insert方法不能正常工作。除了remove函数外,代码中的所有东西都可以正常工作。我有一个名为“insert”的公共空函数,它有一个int参数。@user2782774我知道,但如果一切正常,你就不会有一个NULL作为根。。。。尝试插入和打印一些项目…我检查了,R确实为空,但我不知道当树中有项目时,这是怎么可能的。@user2782774您在未检查的情况下对子项调用remove,这就是为什么
void remove(int x, node * &r)
{
    if(r != NULL)
    {
       // Your code
    }
}
    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);
                }

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

   //... etc.
}