2011-05-18 211 views
1

我有一個簡單的問題,但我不明白我爲什麼擁有它。C++刪除錯誤 - _unlock_fhandle拋出異常?

我將不勝感激任何見解。

我編寫了這段代碼來測試我在Visual Studio 2010中正確創建並使用了Windows 7 64位下可以在Windows XP上執行的DLL。代碼正確執行,並且因爲它是一個小型測試程序,釋放分配的內存並不重要,但肯定會在未來。

我隱式調用DLL,正如我所說,它似乎工作得很好。當我將「delete dllMsg;」行添加到toyUseDLL.cpp時,它崩潰,調試器在osfinfo.c中顯示_unlock_fhandle。

如果它是相關的,我正在用/ MT編譯程序來嵌入運行時庫(只有少數不重要的原因)。

似乎很明顯,我正在釋放未分配的東西,但程序輸出是正確的,因爲指針正在傳遞引用的內存位置。我能想到的唯一的事情就是我的指針是無效的,而且它只是在沒有覆蓋內存的情況下運行。

感謝您的幫助,我對C++很感興趣,並且已經在這個網站上找到了很多很棒的幫助,所以感謝過去發佈的所有人! :-)

msgDLL.h

#include <string> 
using namespace std; 

namespace toyMsgs { 
    class myToyMsgs { 
     public: 
     static __declspec(dllexport) string* helloMsg(void); 
     static __declspec(dllexport) string* goodbyeMsg(void); 
    }; 
} 

msgDLL.cpp

#include <iostream> 
#include <string> 
#include "msgDLL.h" 

using namespace std; 

namespace toyMsgs { 
    string* myToyMsgs::helloMsg(void) { 
     string *dllMsg = new string; 
     dllMsg->assign("Hello from the DLL"); 
     cout << "Here in helloMsg, dllMsg is: \"" << *(dllMsg) << "\"" << endl; 
     return (dllMsg); 
    } 

    string* myToyMsgs::goodbyeMsg(void) { 
     string *dllMsg = new string; 
     dllMsg->assign("Good bye from the DLL"); 
     cout << "Here in goodbyeMsg, dllMsg is: \"" << *(dllMsg) << "\"" << endl; 
     return (dllMsg); 
    } 
} 

toyUseDLL.cpp

#include <iostream> 
#include <string> 

#include "stdafx.h" 
#include "msgDLL.h" 

using namespace std; 

int _tmain(int argc, _TCHAR* argv[]) { 
    string myMsg; 
    string *dllMsg; 

    myMsg.assign ("This is a hello from the toy program"); 
    cout << myMsg << endl; 

    dllMsg = toyMsgs::myToyMsgs::helloMsg(); 
    cout << "Saying Hello? " << *(dllMsg) << endl; 
    delete dllMsg; 

    myMsg.assign ("This is the middle of the toy program"); 
    cout << myMsg << endl; 

    dllMsg = toyMsgs::myToyMsgs::goodbyeMsg(); 
    cout << "Saying goodbye? " << *(dllMsg) << endl; 

    myMsg.assign ("This is a goodbye from the toy program"); 
    cout << myMsg << endl; 

    return 0; 
} 

程序的輸出:

This is a hello from the toy program 
Here in helloMsg, dllMsg is: "Hello from the DLL" 
Saying Hello? Hello from the DLL 
This is the middle of the toy program 
Here in goodbyeMsg, dllMsg is: "Good bye from the DLL" 
Saying goodbye? Good bye from the DLL 
This is a goodbye from the toy program 

回答

2

問題是你使用/ MT來編譯你的EXE和DLL。當你使用/ MT時,每個可執行文件都有自己的C運行時庫副本,這是一個獨立的獨立上下文。當兩個DLL都編譯爲/ MT時,CRT和標準C++庫類型無法安全地通過DLL邊界傳遞。在你的情況下,字符串由一個CRT(在它的私有操作系統堆中)分配,並由EXE(具有不同的堆)釋放,導致有問題的崩潰。

要使程序正常工作,只需編譯/ MD。一般建議:/ MT幾乎從來都不是正確的事情(包括內存成本,性能,服務,安全性和其他一些相對重要的原因)。

馬丁

+0

我在測試環境中工作,尚未能夠部署任何軟件有問題的機器,所以/ MT是一個臨時工作周圍。 – Stephen 2011-05-19 13:26:38