2009-07-22 80 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的地址給構造函數。對象是否有可能假定這個指針的所有權並試圖在析構函數中刪除它?