处理破坏堆的对象

时间:2009-07-22 16:01:42

标签: c++ heap fault-tolerant-heap

在我的应用程序中,我正在创建一个非常类似的对象:

connect() {
  mVHTGlove = new vhtGlove(params);
}

一旦我即将关闭申请,我就称之为:

disconnect() {
  if (mVHTGlove) 
    delete mVHTGlove;
}

此调用始终使用以下消息触发断点:

  

Windows触发了一个断点   DesignerDynD.exe。

     

这可能是由于腐败造成的   堆,表示中的错误   DesignerDynD.exe或它的任何DLL   装了。

     

这也可能是由于用户造成的   在DesignerDynD.exe中按F12   有重点。

     

输出窗口可能有更多   诊断信息。

我无法修改vhtGlove类来修复堆栈损坏,因为它只是以头文件,lib文件和dll的形式提供的外部库。

有没有办法以干净的方式使用这个类?


****编辑:::我试图将事情简化到最低限度,但是我得到了相同的结果......在这里你有完整的代码。

#include "vhandtk/vhtCyberGlove.h"
#include "vhandtk/vhtIOConn.h"
#include "vhandtk/vhtBaseException.h"

using namespace std;

int main(int argc, char* argv[])
{
   vhtCyberGlove* testGlove = NULL;

   vhtIOConn gloveAddress("cyberglove", "localhost", "12345", "com1", "115200");
   try
   {
      testGlove = new vhtCyberGlove(&gloveAddress,false);

      if (testGlove->connect())
         cout << "Glove connected successfully" << endl;
      else
      {
         throw vhtBaseException("testGlove()->connect() returned false.");
      }

      if (testGlove->disconnect())
      {
         cout << "Glove disconnected successfully" << endl;
      }
      else 
      {
         throw vhtBaseException("testGlove()->disconnect() returned false.");
      }

   }
   catch (vhtBaseException *e)
   {
      cout << "Error with gloves: " << e << endl;
      system("pause");
      exit(0);
   }

   delete testGlove;

   return 0;
}

手套被删除时仍然崩溃。


编辑#2 ::如果我只是分配和删除vhtCyber​​Glove的实例,它也会崩溃。

int main(int argc, char* argv[])
{
   vhtCyberGlove* testGlove = NULL;
   vhtIOConn gloveAddress("cyberglove", "localhost", "12345", "com1", "115200");
   testGlove = new vhtCyberGlove(&gloveAddress,false);
   delete testGlove; //<<crash!
   return 0;
}

有什么想法吗?

谢谢!

JC

5 个答案:

答案 0 :(得分:4)

一种可能性是mVHTGlove没有被初始化为0.如果在没有连接被调用的情况下调用disconnect,那么你将尝试释放垃圾指针。吊杆。

另一种可能性是你实际上在此之前有点腐败堆栈,但这就是腐败实际导致崩溃的地方。检查这个问题的一个好方法是尽可能多地注释掉代码并仍然运行程序,然后查看是否仍然存在损坏。如果你不这样做,慢慢地带回一些代码,直到你看到它回来。


进一步的想法(在你的编辑之后)。

您可以检查并查看API是否没有自己的内存管理调用,而不是期望您手动“新建”和“删除”对象。我说这个的原因是我看到一些DLL在DLL内部和一些外部管理某些内存时会出现类似的问题。

答案 1 :(得分:2)

删除vhtGlove时会报告堆损坏错误。但是,它也可能是您自己的代码导致损坏。这通常是由于覆盖堆上分配的缓冲区而导致的,可能来自对malloc的调用。或者您可能两次删除相同的对象。您可以通过使用像std::auto_ptr这样的智能指针来存储指向对象的指针来避免这种情况。

答案 2 :(得分:1)

您可能尝试追踪损坏源的一件事是在检测到堆损坏时使用Visual Sudio的“内存”窗口查看mVHTGlove指向的内存位置。看看你是否在内存中看到任何看起来像是超出缓冲区的内容。例如,如果您看到程序中其他位置使用的字符串,那么请查看操作该字符串的代码 - 它可能会超出其缓冲区。

答案 3 :(得分:1)

鉴于vhtCyber​​Glove的实现是在另一个DLL上,我会寻找堆不匹配。例如,在VS中,如果DLL链接到Release CRT,而EXE链接到Debug CRT,则会发生这种情况。在这种情况下,每个模块使用不同的堆,一旦您尝试使用错误的堆释放内存,您就会崩溃。

在你的情况下,vhtCyber​​Glove可能会获得一些在另一个DLL上分配的东西,但是当你删除vhtCyber​​Glove实例时,东西会被直接删除,即引用你的堆而不是DLL。当试图释放指向另一个堆的指针时,你的实际上会腐蚀你的。

如果确实如此,如果没有更多细节,我可以提供两个修复:

  1. 确保您的EXE使用与DLL相同的堆。可能会锁定你的发布模式,所以这不是最好的方式
  2. 获取vhtCyber​​Glove的提供商以正确管理其内存使用情况......

答案 4 :(得分:1)

您正在将本地vhtIOConn的地址传递给构造函数。对象是否可能拥有此指针的所有权并尝试在析构函数中删除它?