C ++删除错误 - _unlock_fhandle抛出异常?

时间:2011-05-18 19:13:22

标签: visual-c++ dll memory-management

我有一个直截了当的问题,但我不明白我为什么会这样做。

我非常感谢任何见解。

我编写此代码来测试我是否在Win 7 64bit下可以在Windows XP上执行的Visual Studio 2010中正确创建和使用DLL。代码执行正确,因为它是一个小的测试程序,释放分配的内存并不重要,但肯定会在将来。

我隐含地调用DLL,正如我所说,它似乎工作正常。当我向toyUseDLL.cpp添加“delete dllMsg;”行时,它会崩溃,调试器会在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 个答案:

答案 0 :(得分:2)

问题是您使用/ MT编译EXE和DLL。当您使用/ MT时,每个可执行文件都会获得自己的C运行时库副本,这是一个独立且独立的上下文。当两个DLL都被编译/ MT时,CRT和标准C ++库类型无法安全地通过DLL边界传递。在你的情况下,字符串由一个CRT(在其私有操作系统堆上)分配,并由EXE(具有不同的堆)释放,导致有问题的崩溃。

要使程序正常工作,只需编译/ MD。

一般建议:/ MT几乎从来都不是正确的事情(出于少数相对重要的原因,包括内存成本,性能,服务,安全性等)。

马丁

答案 1 :(得分:0)