我遇到的问题是在删除二叉树节点期间收到堆损坏消息。消息说:
HEAP [lab4.exe]:HEAP:空闲堆块5788c0在5788e8之后修改
Windows已在lab4.exe中触发了断点。
这可能是由于堆损坏所致,这表明存在错误
lab4.exe或它已加载的任何DLL。
这也可能是由于用户在lab4.exe具有
焦点。
听起来我正在写入已释放的内存块。 Valgrind似乎通过以下消息确认了这一点:
大小为4的无效写入
在0x8049C65:> BinTree :: removeTree(BinTree :: Node *)(in / net / metis / home2 / alexo2 / lab4 / a.out)...
== 9681 ==地址0x402ab50是大小为12的块内的0个字节
在0x40054B4:运算符delete(void *)(vg_replace_malloc.c:346)
通过0x8049C61:BinTree :: removeTree(BinTree :: Node *)(在
/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
时,将调用它所指向的对象的析构函数,然后调用父对象的析构函数,最后是基类的析构函数(它们都是空的)。有时在父析构函数中,有时在基类析构函数中,显示堆损坏消息。关于该问题可能源于什么的任何建议?
最佳答案
这个:
delete curr->data;
delete curr;
curr->data = NULL;
curr = NULL;
是错的。
curr->data
d delete
之后,您不应该写curr
。甚至没有NULL
。关于c++ - 检测无效写入失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8446275/