【发布时间】:2015-09-22 10:41:47
【问题描述】:
出于练习目的,我正在使用 Trees。目前精确的二叉搜索树。我有一个通用的Tree 类,用于解决 BST 问题。
因此,我遇到了将给定树(BST)转换为双向链表的问题。
我能够成功地将树转换为 DLL。但是,问题是当我打电话给destructor 时。
因为,我正在为树的节点分配内存,所以我也希望释放内存。
这是Tree 类的析构函数 ::
~Tree() {
delete root;
root = NULL;
}
这是Node类的析构函数::
~Node() {
delete left;
delete right;
left = NULL;
right = NULL;
}
所以,程序最后崩溃了! 据我了解,由于我编写的析构函数会递归删除树的所有节点,并且当 Tree 转换为 DLL 时,左右指针确实相互指向,因此,在调用析构函数期间,析构函数尝试删除已被删除且该指针尚未设置为 NULL 的节点。 我该如何克服呢?由于不允许析构函数重载。
有什么办法可以防止这个运行时错误? 这是代码 :: http://ideone.com/SDkXY9 (ideone不打印输出,不知道为什么!)
【问题讨论】:
-
哦,将成员变量设置为
NULL(顺便说一下,使用0或nullptr)只设置that 成员变量,而不是任何其他指针。在析构函数中重置成员变量实际上是没有意义的,因为一旦调用析构函数,对象(及其成员变量)就不再存在了。 -
@user007 这个名字只是一个提示,你可以随便叫它;)
-
你需要检查你的
convertBSTtoDLLUtil函数。当您将root设为另一个节点的子节点时,前一个父节点仍将root作为子节点,并且您会得到多个父节点具有相同的子节点,从而导致您的问题。 -
@user007 看看你的设计。如果我想删除一个节点,不理会树的其余部分怎么办?这不合理吗?当然不是。如果你不能从树上砍下树枝,那树有什么用?但是,您的设计使这项简单的任务变得不可能。当
Node被删除时,析构函数会销毁与其连接的所有节点。这听起来像是一个好的设计吗?让Tree弄清楚在销毁自身时要删除哪些节点。所需要的只是一个简单的递归循环来删除节点。 -
@user007 这真的是一个知道一个节点应该有多少“智能”的问题。该节点应通过
Tree创建、销毁并链接到其他节点。因此,做家务应该是树的责任。通过在 Node 中放置一个析构函数来解除与邻居的链接,你做了一件不可思议的事情——移除一个分支,整棵树就会倒塌。
标签: c++ c++11 tree runtime-error