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
Hosted by :
Copyright ©2007 Pierre Barthe