1

I have a straightforward problem but I don't understand why I have it.

I would greatly appreciate any insight.

I wrote this code to test that I was correctly creating and using DLLs in Visual Studio 2010 under Win 7 64bit that could execute on Windows XP. The code executes correctly, and because it is a small test program freeing the allocated memory is not critical, but certainly will be in the future.

I am implicitly calling the DLL, as I say, it appears to work just fine. When I add the line "delete dllMsg;" to toyUseDLL.cpp it crashes, and the debugger shows _unlock_fhandle in osfinfo.c.

If it's relevant I am compiling the program with /MT to embed the runtime library (for a small handful of not important reasons).

It seems pretty obvious that I'm deallocating something not allocated, but the program output is correct since the pointers are passing the referenced memory locations. The only thing I can think of is that my pointer isn't valid, and it's only working by pure chance that the memory wasn't overwritten.

Thanks for any help, I'm pretty new to C++ and have already found a lot of great help on this site, so thanks for everyone who has posted in the past!! :-)

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;
}

Program Output:

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
Stephen
  • 1,607
  • 2
  • 18
  • 40

2 Answers2

2

The problem is that you are using /MT to compile your EXE and DLL. When you use /MT, each executable gets its own copy of the C runtime library, which is a separate and independent context. CRT and Standard C++ Library types can't safely be passed across the DLL boundary when both DLLs are compiled /MT. In your case the string is allocated by one CRT (on its private OS Heap), and freed by the EXE (which has a different heap) causing the crash in question.

To make the program work, simply compile /MD.

General advice: /MT is almost never the right thing to do (for a large handful of relatively important reasons including memory cost, performance, servicing, security and others).

Martyn

Martyn Lovell
  • 2,086
  • 11
  • 13
  • I'm working in a test environment and not yet able to deploy any software to the machine in question, so /MT was a temporary work around. – Stephen May 19 '11 at 13:26
0

There is some good analysis here Why does this program crash: passing of std::string between DLLs

Community
  • 1
  • 1
ColWhi
  • 1,077
  • 6
  • 16