2011-05-18 215 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