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(点数据)
{
coutdelete
只能用于在堆上使用new
分配的对象
在您的代码中,所有4个节点都已在堆栈上分配,因此对它们调用delete
是一个无效的操作,会导致“未定义的行为”。delete
必须仅用于在堆上分配了new
的对象
在您的代码中,所有4个节点都已在堆栈上分配,因此对它们调用delete
是一个无效的操作,会导致“未定义的行为”。Removedelete这一行。这没有意义。@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