1

在我的应用程序中,我正在创建一个非常像这样的对象:

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

4

5 回答 5

4

一种可能性是 mVHTGlove 没有被初始化为 0。如果在没有调用连接的情况下调用了断开连接,那么您将尝试释放垃圾指针。繁荣。

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


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

您可能会检查 API 是否没有自己的内存管理调用,而不是期望您手动“新建”和“删除”对象。我这样说的原因是我看到一些 DLL 的问题看起来很像这样,当一些内存在 DLL 内部和一些外部进行管理时。

于 2009-07-22T16:09:04.057 回答
2

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

于 2009-07-22T16:08:07.210 回答
1

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

于 2009-07-22T16:12:08.513 回答
1

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

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

如果情况确实如此,我可以提供两个修复,无需更多细节:

  1. 确保您的 EXE 使用与 DLL 相同的堆。可能会将您锁定在发布模式,所以这不是最好的方法
  2. 让 vhtCyber​​Glove 的提供者正确管理其内存使用...
于 2009-07-22T19:43:15.407 回答
1

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

于 2009-07-22T19:55:32.790 回答