无法检测无效写入

时间:2011-12-09 13:39:00

标签: c++ pointers delete-operator heap-corruption

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

  

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时,它所指向的对象的析构函数被调用,然后是父类的析构函数,最后是基类析构函数(所有这些)是空的)。有时它在父析构函数中,有时是基类析构函数,它会显示堆损坏消息。

关于问题可能源于什么的任何建议?

1 个答案:

答案 0 :(得分:1)

此:

delete curr->data;
delete curr;

curr->data = NULL;
curr = NULL;

错了。在curr->data d delete之后,您不应该写信至curr。甚至不是NULL