Problem with /MTd compile option


Thanks in advance for any help. I encounter a problem with VS2005 where the EXE would crash with heap error. I create a simple EXE, DLL to illustrate the problem.

Crash - if I use /MTd in the compile option for the EXE
No Crash - if I use /MDd in the comppile option for the EXE

I mark the place where the crash occurs.


Error Message
-------------

HEAP[EXE.exe]: Invalid Address specified to RtlValidateHeap( 003E0000, 00395BC8 )
Windows has triggered a breakpoint in EXE.exe.


DLL Header
------------

class DLL_API CTestString {
public:
CTestString(void);
void GetValue( wstring &value);

BSTR bsClassStr;
};

// This class is exported from the DLL.dll
class DLL_API CDLL {
public:
CDLL(void);
void Resolve( CTestString** ppCTestString);
};

DLL CPP
---------

void CDLL::Resolve( CTestString** ppCTestString)
{
*ppCTestString = (CTestString*) new CTestString();
}


CTestString::CTestString(void)
{
bsClassStr = ::SysAllocString( L"InsideClass" );
}


void CTestString::GetValue( wstring &ReturnValue)
{
ReturnValue = bsClassStr;
}

EXE
---

{
CDLL* pDllObject;
wstring wsGetString2;
CTestString* pCTestString;

pDllObject = new CDLL();

pDllObject->Resolve( &pCTestString);

pCTestString->GetValue( wsGetString2 );
wprintf( L"DynClass Return string is %s\n", wsGetString2.c_str()); // Strings are printed properly
wprintf( L"DynClass Return string size is %d\n", wsGetString2.size()); // Strings are printed properly

} (<---- ***** CRASH HERE ******** )



Answer this question

Problem with /MTd compile option

  • AtlzBIGuru

    You should use the debugger to further diagnose the problem. You will need to switch to disassembly to get better information. It appears that either

    1. objects going out of scope is causing the crash... within destructors

    2. memory is being overwritten... the return address Watching the stack memory space using memory window might help to see this.

    Brian


  • BradWest

    In this case you should ensure that onl ybasic types are passed and that memory is freed were it is allocated. use of STL data containers is not allowed in this szenario!

  • Myself-Me

    Thanks for your response.

    I added destructors in the DLL but they are never called (in the crashing or non-crashing case). The crash happens in xstring in this line:

    _Mybase::_Alval.deallocate(_Ptr, _Myres + 1);


    XString
    --------



    void __CLR_OR_THIS_CALL _Tidy(bool _Built = false,
    size_type _Newsize = 0)
    { // initialize buffer, deallocating any storage
    if (!_Built)
    ;
    else if (_BUF_SIZE <= _Myres)
    { // copy any leftovers to small buffer and deallocate
    _Elem *_Ptr = _Bx._Ptr;
    if (0 < _Newsize)
    _Traits_helper::copy_s<_Traits>(_Bx._Buf, _BUF_SIZE, _Ptr, _Newsize);
    _Mybase::_Alval.deallocate(_Ptr, _Myres + 1); <----- ***** CRASH HERE *****
    }
    _Myres = _BUF_SIZE - 1;
    _Eos(_Newsize);
    }


  • LordKrishna

    Good that you're going deeper. I think you can go deeper still.

    "Crash" is a general term. Is it an assertion in the CRT memory manager, or an access violation (dereferencing a bad pointer, e.g.), illegal instruction...

    This could be a delayed crash, where the cause is actually earlier than the crash. Try selectively change and/or comment out code in your function to see if you can find the cause. For example, overwrites to heap-allocated memory can cause assertions in the CRT to fire since it checks that guard block values have not been overwritten.

    Brian


  • durstin

    thanks for all responses. I am going to dig a bit deeper and keep in mind consistent CRT.

    This code sample is part of a bigger project. Is it possible to mix a Visual Studio .NET executable with static CRT and a Visual Studio 2005 DLL with static CRT


  • Sumit Ray

    The reason is very simple. You are using two different CRT's. One time the static linked one one time the shared DLL CRT. So if EXE and DLL use different CRT's memory allocations will use two different heaps.

    So you are using a wstring that is returned by the DLL but the buffer is freed in the EXE.

    Always make sure that the same CRT is used if you use derived types that manage there own memory allocation like std::string.

    I wold never design a DLL interface that passes objects like wstring or string, because they are nt universal, depends on the heap implementation and might differ from compiler to compiler.



  • Problem with /MTd compile option