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' 变量。