我遇到的问题是在删除二叉树节点期间收到堆损坏消息。消息说:


  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/

10-11 17:03