C++ 析构函数中的堆栈溢出
Stack overflow in C++ destructor
我尝试创建 detor 并得到了 "Stack Overflow"
我知道为什么,但我想要它的工作...
#include <iostream>
#include "printTreeToFile.h"
#include "BSNode.h"
#define _BS BSNode::
#define _BSNode _BS BSNode
_BS ~BSNode()
{
Del(this);
}
void _BS Del(BSNode *x,int y)
{
if (x->isLeaf())
{
delete x;
return;
}
if (x->_Right != NULL)
Del(x->_Right,y += 1);
if (x->_Left != NULL)
Del(x->_Left,y += 1);
if (y != 1)
{
delete x;
}
return;
}
我尝试以递归方式执行此操作,但对 Del 的删除调用如此
我们有无限循环
通过调用 delete x
,您在调用节点析构函数的函数中调用节点的析构函数。不需要在析构函数中销毁实际对象。
_BS ~BSNode()
{
Del(this);
}
void _BS Del(BSNode *x,int y)
{
if (x->isLeaf())
{
delete x;
return;
}
if (x->_Right != NULL)
Del(x->_Right,y += 1);
if (x->_Left != NULL)
Del(x->_Left,y += 1);
if (y != 1)
{
delete x;
}
return;
}
您正在递归删除 this
。你不需要这一切。你想多了您只需要:
BSNode::~BSNode()
{
delete _Left;
delete _Right;
}
这将自动递归左右子树,并在 null 处停止。
析构函数是一个允许对象释放它拥有的资源的函数。对象本身的销毁:
- 如果对象在堆栈上分配并且您的代码退出其声明块,则自动完成。
- 调用代码通过 delete 关键字明确完成。
- 还有更多(参见 N3242 中的第 12.4.10 节)
你在这里试图做的是从它的 owd 析构函数中删除对象本身。通过这样做,您对 delete 的调用将触发对析构函数的调用,该析构函数本身调用其析构函数。
您的问题的解决方案是仅销毁 BSNode 对象拥有的资源(可能是 _Right 和 _Left)。如果子节点没有价值,那么销毁链就会停止。
invoking delete on a null pointer has no effect (see § 12.4.12 from N3242)
对于您的情况,只需执行以下操作:
void _BS Del(BSNode *x)
{
delete _Right;
delete _Left
}
抱歉,我不明白为什么要在您的代码中引入 'y' 变量。
我尝试创建 detor 并得到了 "Stack Overflow" 我知道为什么,但我想要它的工作...
#include <iostream>
#include "printTreeToFile.h"
#include "BSNode.h"
#define _BS BSNode::
#define _BSNode _BS BSNode
_BS ~BSNode()
{
Del(this);
}
void _BS Del(BSNode *x,int y)
{
if (x->isLeaf())
{
delete x;
return;
}
if (x->_Right != NULL)
Del(x->_Right,y += 1);
if (x->_Left != NULL)
Del(x->_Left,y += 1);
if (y != 1)
{
delete x;
}
return;
}
我尝试以递归方式执行此操作,但对 Del 的删除调用如此 我们有无限循环
通过调用 delete x
,您在调用节点析构函数的函数中调用节点的析构函数。不需要在析构函数中销毁实际对象。
_BS ~BSNode()
{
Del(this);
}
void _BS Del(BSNode *x,int y)
{
if (x->isLeaf())
{
delete x;
return;
}
if (x->_Right != NULL)
Del(x->_Right,y += 1);
if (x->_Left != NULL)
Del(x->_Left,y += 1);
if (y != 1)
{
delete x;
}
return;
}
您正在递归删除 this
。你不需要这一切。你想多了您只需要:
BSNode::~BSNode()
{
delete _Left;
delete _Right;
}
这将自动递归左右子树,并在 null 处停止。
析构函数是一个允许对象释放它拥有的资源的函数。对象本身的销毁:
- 如果对象在堆栈上分配并且您的代码退出其声明块,则自动完成。
- 调用代码通过 delete 关键字明确完成。
- 还有更多(参见 N3242 中的第 12.4.10 节)
你在这里试图做的是从它的 owd 析构函数中删除对象本身。通过这样做,您对 delete 的调用将触发对析构函数的调用,该析构函数本身调用其析构函数。
您的问题的解决方案是仅销毁 BSNode 对象拥有的资源(可能是 _Right 和 _Left)。如果子节点没有价值,那么销毁链就会停止。
invoking delete on a null pointer has no effect (see § 12.4.12 from N3242)
对于您的情况,只需执行以下操作:
void _BS Del(BSNode *x)
{
delete _Right;
delete _Left
}
抱歉,我不明白为什么要在您的代码中引入 'y' 变量。