我遇到的问题是我在删除二叉树节点时遇到了堆损坏消息。消息说:
HEAP [lab4.exe]:HEAP:自由堆块5788c0在5788e8后修改 它被释放Windows已经在lab4.exe中触发了一个断点。
这可能是由于堆的损坏,这表明存在错误 lab4.exe或它加载的任何DLL。
这也可能是因为用户在lab4.exe时按F12 对焦。
听起来我正在写一个已被释放的内存块。 Valgrind似乎用以下消息证实了这一点:
写入大小4无效
在0x8049C65:> BinTree :: removeTree(BinTree :: Node *)(在/ net / metis / home2 / alexo2 / lab4 / a.out中)
...
== 9681 ==地址0x402ab50是一个大小为12的块中的0字节
在0x40054B4:operator delete(void *)(vg_replace_malloc.c:346) by 0x8049C61:BinTree :: removeTree(BinTree :: Node *)(in /net/metis/home2/alexo2/lab4/a.out)
...
当我浏览程序时,堆损坏消息通常在父类或基类析构函数中开始。我一直试图追踪这个,但我不知道问题出在哪里。在析构函数之前,我从不在这些节点上使用delete。
我怀疑这个问题与我删除或跟踪二叉树的方式有关。这是我发布的一些代码,不确定它是否有助于找到解决方案。
因此,一个类对象是由一个函数动态分配和返回的。使用指针跟踪此对象,直到它最终插入到二叉树的节点中。 在程序结束时删除所有内容时,将调用析构函数:
void BinTree::makeEmpty()
{
if ( root != NULL ) {
removeTree( root );
}
root = NULL;
}
void BinTree::removeTree( Node *curr )
{
if ( curr == NULL )
return;
removeTree( curr->left );
removeTree( curr->right );
delete curr->data;
delete curr;
curr->data = NULL;
curr = NULL;
}
在某些函数中,这是创建并返回动态分配对象的调用:
Item *aMovie = factory.createMovie( code.c_str() );
只有部分节点,而不是所有节点,当到达delete curr->data
时,它所指向的对象的析构函数被调用,然后是父类的析构函数,最后是基类析构函数(所有这些)是空的)。有时它在父析构函数中,有时是基类析构函数,它会显示堆损坏消息。
关于问题可能源于什么的任何建议?
答案 0 :(得分:1)
此:
delete curr->data;
delete curr;
curr->data = NULL;
curr = NULL;
错了。在curr->data
d delete
之后,您不应该写信至curr
。甚至不是NULL
。