2009-07-22 48 views
1

在我的应用我创建一个对象非常类似这样的:与对象处理损坏堆

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

,一旦我即将关闭应用程序,我称它是:

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

此调用总是触发一个带有以下消息的断点:

Windows触发了一个断点 Des ignerDynD.exe。

这可能是由于 堆,这表明在 DesignerDynD.exe或任何它 已加载的DLL的一个错误的损坏。

这也可能是由于用户 按F12而DesignerDynD.exe 有焦点。

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

我无法修改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

+3

请注意,您不需要检查_mVHTGlove_不是_NULL_。它很好地定义了将_NULL_指针传递给_delete_。 – sbi 2009-07-22 16:15:14

+0

disconnect()调用了多少次? – MSN 2009-07-22 16:44:53

+0

只是一次。 。 – levesque 2009-07-22 16:56:45

回答

4

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

另一种可能性是,你实际上在这个点之前腐蚀了堆栈,但那是腐败实际导致崩溃的地方。检查的一种好方法是尽可能多地评论代码,然后让程序运行,然后看看你是否仍然受到损坏。如果你不这样做,慢慢地回复一些代码,直到你看到它回来。


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

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

2

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

1

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

1

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

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

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

  1. 确保您的EXE使用同一个堆的DLL。可能会锁定您在Release模式,所以它不是去
  2. 获取vhtCyber​​Glove的供应商,以妥善管理其内存使用情况的最好方法...
1

你传入本地vhtIOConn的地址给构造函数。对象是否有可能假定这个指针的所有权并试图在析构函数中删除它?