简体   繁体   English

成员指针在函数返回时被覆盖?

[英]Member pointer being overwritten on function return?

I've been practicing my C++, as it's gotten a little rusty since college, and I'm having a bizarre problem where a member value is being overwritten as soon as my function returns. 我一直在练习我的C ++,因为它从大学开始就变得有点生疏了,而且我有一个奇怪的问题,一旦我的函数返回,成员值就会被覆盖。

template <class T>
class BstNode
{
    public:
        T value;
        BstNode<T>* left;
        BstNode<T>* right;
        BstNode<T>* parent;

        BstNode()
        { left = right = parent = NULL; }
        BstNode(T value)
        { this->value=value; left=right=parent=NULL;}
        BstNode(T value, BstNode<T>* parent)
        { this->value=value; this->parent=parent; left=right=NULL;}
};

template <class T>
class BinarySearchTree 
{
    protected:
        BstNode<T>* root;

        void removeNode(BstNode<T>* node);
        void addChild(T value, BstNode<T>* node);
        BstNode<T>* find(T value, BstNode<T>* node);
    public:
        BinarySearchTree()
        { root = NULL; }
        ~BinarySearchTree()
        { removeNode(root); }

        BinarySearchTree<T> insert(T value);
        bool contains(T value);
        BinarySearchTree<T> remove(T value);

        void print();

        BstNode<T>* getRoot() {return root;}

};

template <class T>
BinarySearchTree<T> BinarySearchTree<T>::insert(T value)
{
    if (root == NULL)
    {
        root = new BstNode<T>(value);       
    }
    else
    {
        addChild(value, root);
    }
    cout << "VAL: " << root->value << endl << "LEFT: " << root->left << endl << "RIGHT: "<< root->right << endl << "ADDR: " << root <<endl;
    return *this;
}
template <class T>
void BinarySearchTree<T>::addChild(T value, BstNode<T>* node)
{

    if (value > node->value)
    {
        cout <<"\tgt"<<endl;
        if (node->right == NULL)
        {
            node->right = new BstNode<T>(value, node);
        }
        else
        {
            addChild(value, node->right);
        }
    }
    else
    {
        cout<<"\tlte"<<endl;
        if (node->left == NULL)
        {
            node->left = new BstNode<T>(value, node);
        }
        else
        {
            addChild(value, node->left);
        }
    }
}

// [other member functions]


int main()
{
    BinarySearchTree<int> tree;
    BstNode<int> *n;
    n = tree.getRoot();
    cout << "ADDR: " << n <<endl<<endl;
    tree.insert(5);
    n = tree.getRoot();

    cout << "VAL: " << n->value << endl << "LEFT: " << n->left << endl << "RIGHT: "<< n->right << endl << "ADDR: " << n << endl;
    return 1;
}

The output of my function is: 我的函数的输出是:

$ ./bst
ADDR: 0

VAL: 5
LEFT: 0
RIGHT: 0
ADDR: 0xa917c8

VAL: 11085080
LEFT: 0xa917a8
RIGHT: 0
ADDR: 0xa917c8

I don't understand why the values in the root node changed, but the pointer is still pointing at the same location. 我不明白为什么根节点中的值会更改,但是指针仍然指向同一位置。 The only thing I could think of is that the root node is being created on the stack instead being allocated in the heap, but doesn't new make sure that memory is allocated correctly in C++? 我唯一想到的是,根节点是在堆栈上创建的,而不是在堆中分配的,但是不是new来确保在C ++中正确分配了内存吗?

I think the issue is that your insert method returns the BinarySearchTree by value, but you don't have a copy constructor defined. 我认为问题是您的insert方法按值返回BinarySearchTree,但您没有定义复制构造函数。 As a result, this makes a shallow copy of the BinarySearchTree, returns it, and causes the copy's destructor to fire. 因此,这会生成BinarySearchTree的浅表副本,返回它,并导致副本的析构函数触发。 This then deletes the BstNode stored as the root, but since the copied BinarySearchTree shares BstNodes with the original tree, you're trashing memory in the original tree. 然后删除存储为根的BstNode,但由于复制的BinarySearchTree与原始树共享BstNode,因此您将在原始树中丢弃内存。 The error you're getting is from accessing deallocated memory when you try to access the node again. 当您尝试再次访问该节点时,遇到的错误是访问已释放的内存。

To fix this, either have the insert function return a reference to the tree (so no copy is made) or define a copy constructor or assignment operator. 要解决此问题,要么让insert函数返回对树的引用(因此不进行复制),要么定义复制构造函数或赋值运算符。 Ideally, do both. 理想情况下,两者都做。 :-) :-)

Hope this helps! 希望这可以帮助!

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

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