C++ free():无效指针:在C++;

C++ free():无效指针:在C++;,c++,tree,C++,Tree,我创建了树数据结构,但在擦除对象时遇到问题 问题内容如下: *在“./t”中出错:free():无效指针:0x00007ffd1df99400* 중지됨 (堆芯倾倒) 源代码 main.cpp #include<iostream> #include"tree.h" #include"point.h" using namespace std; template<class T> void ShowIntData(Point<T> data) { c

我创建了树数据结构,但在擦除对象时遇到问题
问题内容如下:

*在“./t”中出错:free():无效指针:0x00007ffd1df99400*

중지됨 (堆芯倾倒)

源代码

main.cpp

#include<iostream>
#include"tree.h"
#include"point.h"


using namespace std;

template<class T>
void ShowIntData(Point<T> data)
{
    cout<<data.x<<" "<<data.y<<endl;
}

typedef Point<double> pd;

int main(void)
{
    BTreeNode<pd> bt1; bt1.make();
    BTreeNode<pd> bt2; bt2.make();
    BTreeNode<pd> bt3; bt3.make();
    BTreeNode<pd> bt4; bt4.make();

    bt1.SetData(pd(1,10));
    bt2.SetData(pd(2,20));
    bt3.SetData(pd(3,30));
    bt4.SetData(pd(4,40));

    bt1.MakeLeftSubTree(&bt2);
    bt1.MakeRightSubTree(&bt3);
    bt2.MakeLeftSubTree(&bt4);

    bt1.InorderTraverse(ShowIntData);
    cout<<endl;

    bt1.PreorderTraverse(ShowIntData);
    cout<<endl;

    bt1.PostorderTraverse(ShowIntData);
    cout<<endl;

    bt1.DeleteTree(); // Error occurred
    return 0;
}
#包括
#包括“tree.h”
#包括“h点”
使用名称空间std;
样板
void ShowIntData(点数据)
{

cout
delete
只能用于在堆上使用
new
分配的对象


在您的代码中,所有4个节点都已在堆栈上分配,因此对它们调用
delete
是一个无效的操作,会导致“未定义的行为”。

delete
必须仅用于在堆上分配了
new
的对象


在您的代码中,所有4个节点都已在堆栈上分配,因此对它们调用
delete
是一个无效的操作,会导致“未定义的行为”。

Remove
delete这一行。这没有意义。@bendervaid AFAIK这是有效的。(不过,有一件事是无效的,那就是对空指针调用DeleteTree,但许多编译器都允许这样做)@immibis它是无效的,因为所讨论的对象是在堆栈上分配的,而不是在堆上。@JonathanPotter我的意思是
删除这个;
是有效的,只要
这个
是用
新的
分配的。在这种情况下,除了一个(每棵树)对象外,所有对象都是用
新的
分配的。“bug”可能是
删除这一行;
,也可能是这些对象是堆栈分配的。我误解了内存和指针。删除
删除这一行是没有意义的。@bendervaider AFAIK它是有效的。(虽然有一件事是无效的,对空指针调用DeleteTree,但许多编译器都允许这样做)@immibis它是无效的,因为所讨论的对象是在堆栈上分配的,而不是在堆上。@JonathanPotter我的意思是
删除这个;
是有效的,只要
这个
是用
新的
分配的。在这种情况下,除了一个(每棵树)对象外,所有对象都是用
新的
分配的。“bug”可能是
删除这个;
,也可能是这些对象是堆栈分配的。我误解了内存和指针。
#ifndef __T_POINT_H__
#define __T_POINT_H__

template<class T>
struct Point
{
    T x;
    T y;
    Point() : x(0),y(0){}
    Point(T x,T y) : x(x),y(y) {}
};

#endif
#ifndef __B_TREE_H__
#define __B_TREE_H__
#include<iostream>
#include<cstdlib>
using namespace std;

template<class T>
class BTreeNode
{
    private:
        T data;
        BTreeNode<T>* left;
        BTreeNode<T>* right;
    public:
    typedef void VisitFuncPtr(T data);
        BTreeNode();
        BTreeNode<T>* make();
        ~BTreeNode();
        T GetData();
        void SetData(T data);
        BTreeNode<T>* GetLeftSubTree();
        BTreeNode<T>* GetRightSubTree();
        void MakeLeftSubTree(BTreeNode<T>* sub);
        void MakeRightSubTree(BTreeNode<T>* sub);
        void DeleteTree();

        void InorderTraverse(VisitFuncPtr action);  //중위 순회
        void PreorderTraverse(VisitFuncPtr action); //전위 순회
        void PostorderTraverse(VisitFuncPtr action); // 후위 순회

};

template<class T>
BTreeNode<T>::BTreeNode()
{
    left = NULL;
    right = NULL;
}

template<class T>
BTreeNode<T>::~BTreeNode()
{
    cout<<"Destructor"<<endl;
}


template<class T>
BTreeNode<T>* BTreeNode<T>::make(void)
{
    left = NULL;
    right = NULL;
    return this;
}

template<class T>
T BTreeNode<T>::GetData()
{
    return data;
}

template<class T>
void BTreeNode<T>::SetData(T data)
{
    this->data = data;
}

template<class T>
BTreeNode<T>* BTreeNode<T>::GetLeftSubTree()
{
    return left;
}

template<class T>
BTreeNode<T>* BTreeNode<T>::GetRightSubTree()
{
    return right;
}

template<class T>
void BTreeNode<T>::MakeLeftSubTree(BTreeNode<T>* sub)
{
    if(this->left != NULL)
        delete this->left;
    this->left = sub;
}

template<class T>
void BTreeNode<T>::MakeRightSubTree(BTreeNode<T>* sub)
{
    if(this->right != NULL)
        delete this->right;
    this->right = sub;
}

template<class T>
void BTreeNode<T>::InorderTraverse(VisitFuncPtr action)
{
    if(this==NULL)
        return;

    left->InorderTraverse(action);
    action(data);
    right->InorderTraverse(action);

}

template<class T>
void BTreeNode<T>::PreorderTraverse(VisitFuncPtr action)
{
    if(this==NULL)
        return;
    action(data);
    left->PreorderTraverse(action);
    right->PreorderTraverse(action);
}

template<class T>
void BTreeNode<T>::PostorderTraverse(VisitFuncPtr action)
{
    if(this==NULL)
        return;
    left->PostorderTraverse(action);
    right->PostorderTraverse(action);
    action(data);
}

template<class T>
void BTreeNode<T>::DeleteTree()
{
    if(this==NULL)
        return;

    left->DeleteTree();
    right->DeleteTree();

    delete this; //Error occurred


}


#endif