C++ 类成员函数正常工作,但当作为另一个类的数据成员调用时,会陷入无限循环

C++ 类成员函数正常工作,但当作为另一个类的数据成员调用时,会陷入无限循环,c++,loops,tree,infinite,C++,Loops,Tree,Infinite,我编写了一个树结构,并创建了一个基本的搜索函数来查找树中的节点。树本身使用一个sentinel节点来标记所有端点(根的父节点,叶的子节点),搜索只是在节点间迭代,直到找到匹配项或命中sentinel节点。当我在树的实例上调用search函数时,它工作得很好,但是当树是另一个类的数据成员时,它会被卡住。在下面的代码中,“t.search(1)”起作用,但“embedded_tree.t.search(1)”陷入无限循环 我已经将它缩小到这样一个事实,即当调用embedded_tree.t.sear

我编写了一个树结构,并创建了一个基本的搜索函数来查找树中的节点。树本身使用一个sentinel节点来标记所有端点(根的父节点,叶的子节点),搜索只是在节点间迭代,直到找到匹配项或命中sentinel节点。当我在树的实例上调用search函数时,它工作得很好,但是当树是另一个类的数据成员时,它会被卡住。在下面的代码中,“t.search(1)”起作用,但“embedded_tree.t.search(1)”陷入无限循环

我已经将它缩小到这样一个事实,即当调用embedded_tree.t.search()时,“&sentinel”的内容正确地指向sentinel节点,但似乎是一个新指针,因为它不等同于root、sentinel.parent和sentinel.child的内容。从这里开始,我陷入了困境,不知道如何调用它,以便&sentinel与构建树时创建的指针相匹配

#include <iostream>

struct NODE {
    int key;
    NODE* parent;
    NODE* child;
    NODE() : key(0), parent(NULL), child(NULL) {};
};

struct TREE {
    NODE sentinel;
    NODE* root;

    TREE()
    {
        sentinel = *new NODE;
        sentinel.parent = &sentinel;
        sentinel.child = &sentinel;
        root = &sentinel;
    }

    NODE* search(int k)
    {
        NODE* x = root;
        while (x != &sentinel)
        {
            if (x->key == k) return x;
            x = x->child;
        }
        return &sentinel;
    }
};

struct A {
    TREE t;

    A() : t(*new TREE()) {};
};

int main()
{
    TREE t;
    t.search(1);

    A embedded_tree;
    embedded_tree.t.search(1);
}
#包括
结构节点{
int键;
节点*父节点;
节点*子节点;
NODE():键(0),父(NULL),子(NULL){};
};
结构树{
淋巴结哨兵;
节点*根;
树()
{
sentinel=*新节点;
sentinel.parent=&sentinel;
sentinel.child=&sentinel;
根=&哨兵;
}
节点*搜索(int k)
{
节点*x=根;
while(x!=&sentinel)
{
如果(x->key==k)返回x;
x=x->child;
}
回归与哨兵;
}
};
结构A{
树t;
A():t(*new TREE()){};
};
int main()
{
树t;
t、 搜查(1);
嵌入的树;
嵌入树t.search(1);
}

您混淆了动态内存分配和堆栈分配。当你这样做的时候

sentinel = *new NODE
坏事发生了。为堆栈上的
节点sentinel
分配内存,然后为
操作符中的
节点
分配内存,然后为
sentinel
变量分配内存,在
操作符中创建的内存丢失。您应该重写代码以使用指针,并添加析构函数,如下所示

#include <iostream>

struct NODE {
    int key;
    NODE* parent;
    NODE* child;
    NODE() : key(0), parent(NULL), child(NULL) {};
};

struct TREE {
    NODE* sentinel;
    NODE* root;

    TREE()
    {
        sentinel = new NODE;
        sentinel->parent = sentinel;
        sentinel->child = sentinel;
        root = sentinel;
    }

    ~TREE() {
        if (NULL != sentinel) {
            delete sentinel;
            sentinel = NULL;
            root = NULL;
        }
    }

    NODE* search(int k)
    {
        NODE* x = root;
        while (x != sentinel)
        {
            if (x->key == k) return x;
            x = x->child;
        }
        return sentinel;
    }


};

struct A {
    TREE* t;

    A() : t(new TREE()) {};
    ~A() {
        if (NULL != t) {
            delete t;
            t = NULL;
        }

    }
};

int main()
{
    TREE t;
    t.search(1);

    A embedded_tree;
    embedded_tree.t->search(1);
}
#包括
结构节点{
int键;
节点*父节点;
节点*子节点;
NODE():键(0),父(NULL),子(NULL){};
};
结构树{
节点*哨兵;
节点*根;
树()
{
sentinel=新节点;
sentinel->parent=sentinel;
哨兵->儿童=哨兵;
根=哨兵;
}
~TREE(){
如果(空!=哨兵){
删除哨兵;
sentinel=NULL;
root=NULL;
}
}
节点*搜索(int k)
{
节点*x=根;
while(x!=哨兵)
{
如果(x->key==k)返回x;
x=x->child;
}
返回哨兵;
}
};
结构A{
树*t;
A():t(新树()){};
~A(){
如果(NULL!=t){
删除t;
t=零;
}
}
};
int main()
{
树t;
t、 搜查(1);
嵌入的树;
嵌入式_tree.t->search(1);
}

但是,既然我们在讨论C++,我建议您在熟悉手动内存管理之后,先看智能指针和容器。< /P> <代码> StimeNe= *新节点;

不是一个好主意。
t(*new TREE())
——你为什么要这样做?除非指定给指针,否则不使用
new
,除非需要(提示:此处不需要,会导致内存泄漏)。当跟踪
嵌入的_树.t.search(1)时,调试器会告诉您什么函数调用?我很感谢您的反馈,在这里创建sentinel和A.t成员的推荐方法是什么?我的调试器没有说任何我能说的,当我跟踪它时,它只是在while(x!=&sentinel)无限循环,因为两者永远不会相等。然而,当它被称为t.search(1)时,这不会发生;