使用二进制研究树时无效的内存访问

时间:2014-03-31 08:17:48

标签: c++

这是我的代码。

#include<iostream>

template<class Elem>
class BinNode
{
public:
    virtual Elem& getVal() = 0;
    virtual void setVal(const Elem&) = 0;
    virtual BinNode* left() = 0;
    virtual BinNode* right() = 0;
    virtual void setLeft(BinNode*) = 0;
    virtual void setRight(BinNode*) = 0;
    virtual bool isLeaf() = 0;
};//abstract class

template<class Elem>
class BinNodePtr:public BinNode<Elem>
{
public:
    Elem val;
    BinNodePtr* lc;
    BinNodePtr* rc;
    BinNodePtr()
    {
        lc = rc = NULL;
    }
    ~BinNodePtr()
    {
        delete lc;
        delete rc;
    }
    void setVal(const Elem& e)
    {
        val = e;
    }
    Elem& getVal()
    {
        return this->val;
    }
    void setLeft(BinNode<Elem>* e)
    {
            lc = (BinNodePtr<Elem>*)e;
    }
    void setRight(BinNode<Elem>* e)
    {
        rc = (BinNodePtr<Elem>*)e;
    }
    bool isLeaf()
    {
        if(this->lc == NULL && this->rc == NULL)
        return true;
        return false;
    }
    BinNodePtr<Elem>* left()
    {
        return lc;
    }
    BinNodePtr<Elem>* right()
    {
        return rc;
    }
};

template<class Elem>
class BST
{
public:
    BinNodePtr<Elem> *root;
    int nodenum;
    void deleteElem(BinNodePtr<Elem>* start);
    void midorder(BinNodePtr<Elem>* start);
public:
    BST()
    {
        root = NULL;
        nodenum = 0;
    }
    ~BST()
    {
        deleteElem(root);
    }
    bool insert(BinNodePtr<Elem>* ptr,const Elem &e);
    BinNodePtr<Elem>* getRoot(){return root;}
};
template<class Elem>
void BST<Elem>::deleteElem(BinNodePtr<Elem>* start)
{
    BinNodePtr<Elem>* temp =(BinNodePtr<Elem>*) start;
    if(temp == NULL) return;
    deleteElem((BinNodePtr<Elem>*)temp->left());
    deleteElem((BinNodePtr<Elem>*)temp->right());
    delete temp;
}

template<class Elem>
void BST<Elem>::midorder(BinNodePtr<Elem> *start)
{
    if(start == NULL) return;
    midorder(start->lc);
    printf("%d ",start->getVal());
    midorder(start->rc);
}

template<class Elem>
bool BST<Elem>::insert(BinNodePtr<Elem>*ptr,const Elem &e)
{
    if(ptr == NULL)
    {
        ptr = new BinNodePtr<Elem>;
        ptr->lc = NULL;
        ptr->rc = NULL;
        ptr->val = e;
        return true;
    }
    else
    {
        if(ptr->val < e || ptr->val == e)
            {
        ptr = ptr->right();
        insert(ptr->rc,e);
        }
        else
            {
        ptr = ptr->left();
        insert(ptr->lc,e);
            }
    }
    return false;
}

int main()
{
    BST<int> myBST;
    myBST.insert(myBST.root,10);
    myBST.insert(myBST.root,20);
    myBST.insert(myBST.root,5);
    myBST.insert(myBST.root,30);
    printf("%d",myBST.getRoot()->getVal());

    system("pause");
    return 0;
}

有些功能在我的程序中没有使用。我专注于&#34;插入&#34;函数。当我调试这个程序时,程序在printf("%d",myBST.getRoot()->getVal());处失效说&#34;无效的内存访问&#34;,为什么以及如何解决它?

2 个答案:

答案 0 :(得分:0)

如果要更改insert函数中的ptr参数,则应传递它的地址,如下所示:

template<class Elem>
bool BST<Elem>::insert(BinNodePtr<Elem>**ptr,const Elem &e)

或传递对它的引用。

答案 1 :(得分:0)

您必须记住,在C ++中,参数默认按值传递,这意味着它们的值被复制到被调用函数中的参数。更改函数中的参数时,只更改其本地副本,不会将对副本的更改传播给调用者。

要更改调用者中的参数,您必须通过引用传递它,例如

bool insert(BinNodePtr<Elem>*& ptr,const Elem& e);

这将使ptr参数成为对指针的引用,因此对它的更改将传播给调用者。