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 ******** )

Problem with /MTd compile option
Paulino PP
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);
}
Keros
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
phradecky
reboard
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
angelok
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.
dreameR.78
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