Why You shouldn't mix microsoft dynamic runtimes in your applications
Copyright © 2007 Pierre Barthe

This sample illustrates the flaw you expose your native application
when linking against multiple Microsoft dynamic runtimes

The sample is composed of two dynamic libraries :  malloc-vs8_debug.dll and  malloc-vs9_debug.dll
and an executable.
malloc-vs8_debug.dll is linked against msvcr80d.dll and malloc-vs9_debug.dll is linked against msvcr90d.dll
the test_crt executable can be linked either against Microsft Debug 8.0 CRTs (msvcr80d) or Microsft Debug 9.0 CRTs (msvcr90d) dlls :

This sample is using  Microsoft compilers and linker tools, meanwhile do not focus on this:
the __declspec is a compiler specific langage extension , dont focus on this neither:
 
malloc-vs9_debug.dll source :

#include <stdlib.h>

__declspec(dllexport) void *malloc_vs9(size_t sz)
{

return
malloc(sz);
}


__declspec(dllexport) void free_vs9(void *mem)
{

free(mem);
}



and malloc-vs8_debug.dll source is:


#include <stdlib.h>

__declspec(dllexport) void *malloc_vs8(size_t sz)
{

return
malloc(sz);
}


__declspec(dllexport) void free_vs8(void *mem)
{

free(mem);
}

while test_crt.exe is :

#pragma comment(lib,"malloc-vs9_debug.lib")

#pragma comment(lib,"malloc-vs8_debug.lib")

__declspec(dllimport) void *malloc_vs8(size_t sz);
__declspec(dllimport) void free_vs8(void *mem);
__declspec(dllimport) void *malloc_vs9(size_t sz);
__declspec(dllimport) void free_vs9(void *mem);

int
main()
{

void *mem = malloc_vs8(1);
free_vs9(mem);
//res = _CrtCheckMemory ();
return
0; // if getting there return 0 we passed: check your compiler settings
}


test_crt will assert as follows:

HEAP[test_crt.exe]: Invalid Address specified to RtlValidateHeap( ..., ...)
This may be due to a corruption of the heap, and indicates a bug in test_crt.exe or any of the DLLs it has loaded.

when calling free from free_vs9




A correct version might be:

__declspec(dllimport) void *malloc_vs8(size_t sz);
__declspec(dllimport) void free_vs8(void *mem);


int
main()
{

void *mem_vs8 = malloc_vs8(1);
free_vs8(mem_vs8);
//res = _CrtCheckMemory ();
return
0;
}


Note that :

__declspec(dllimport) void *malloc_vs8(size_t sz);
__declspec(dllimport) void free_vs8(void *mem);
__declspec(dllimport) void *malloc_vs9(size_t sz);
__declspec(dllimport) void free_vs9(void *mem);

int main()
{

void *mem_vs9;
void *mem_vs8 = malloc_vs8(1);
free_vs8(mem_vs8);

mem_vs9 = malloc_vs9(1);
free_vs9(mem_vs9); //res = _CrtCheckMemory ();
return
0;
}


is correct.




Meanwhile, don't be disappointed if you are not familiar with the above :
Compare it with the following situation :
You get credit from one bank ,
and pay back the loan to another one :
The second banker should (you must read must) advise you
about your mistake and abort the transaction.  
In the above , the software will stop functionning,
meanwhile there are several ways to handle such failures.
Best practices should avoid such situations.

 
You have been warned you can go to either: GIMPVS Home Page
or: GTK+ SDK Quick Start Guide






Hosted by :
SourceForge.net Logo

Copyright ©2007 Pierre Barthe