Invalid Address specified to RtlValidateHeap 错误
前几天修改了毕设程序的debug版本的bug, 看来自己内功还是不足呀
(转自)Invalid Address specified to RtlValidateHeap
http://hi.baidu.com/%CD%F5%D4%DA%D1%A7vs%D0%A1%C3%C3%C3%C3/blog/item/c0fdb409c1da9c216a60fbc5.html
当使用CRT动态链接时,有于每个dll都是去调用CRT库的dll函数来分配和释放内存的,使用的是同一个句柄,所以就没有这个问题。
在编译的时候,exe和dll有可能链接的是静态的运行时库,也有可能链接的是dll版本的运行时库。如果在exe或者是dll中有一个链接的是静态的运行时库,那么就会存在两套内存分配的实例。所以在dll中申请的内存,到exe中释放就会失败,因为exe并不认识那块内存。解决的办法就是都使用dll版本的运行时库,这样,在进程空间内,只有一个运行时实例。
famel2003-12-12 02:22 AM
在MSDN中看到的一篇与此有关的文章This article was previously published under Q190799
SYMPTOMS
When you pass C Run-time (CRT) objects such as file handles, locales, and environment variables into or out of a DLL (function calls across the DLL boundary), unexpected behavior can occur if the DLL, as well as the files calling into the DLL, use different copies of the CRT libraries.
A related problem can occur when you allocate (explicitly with new, malloc, or implicitly with strdup, strstreambuf::str, and so on) and then pass a pointer across a DLL boundary to be freed. This can cause a memory access violation or heap corruption if the DLL and its users use different copies of the CRT libraries.
Another symptom of this problem can be an error in the output window during debugging such as:
HEAP[]: InvalidAddressspecifiedtoRtlValidateHeap(#,#)
CAUSE
Each copy of the CRT library has a separate and distinct state. As such, CRT objects such as file handles, environment variables, and locales are only valid for the copy of the CRT where these objects are allocated or set. When a DLL and its users use different copies of the CRT library, you cannot pass these CRT objects across the DLL boundary and expect them to be picked up correctly on the other side.
Also, because each copy of the CRT library has its own heap manager, allocating memory in one CRT library and passing the pointer DLL boundary to be freed by a different copy of the CRT library is a potential cause for heap corruption.
If you design your DLL so that it passes CRT objects across the boundary or allocates memory and expects it to be freed outside the DLL, you restrict the DLL users to use the same copy of the CRT library as the DLL. The DLL and its users use the same copy of the CRT library only if both are linked with the same version of the CRT DLL. This could be a problem if you mix applications built with Visual C++ 5.0 with DLLs that are built by Visual C++ 4.1 or earlier. Because the DLL version of the CRT library used by Visual C++ 4.1 is msvcrt40.dll and the one used by Visual 5.0 is msvcrt.dll, you cannot build your application to use the same copy of the CRT library as these DLLs.
However, there is an exception. In US English version and some other localized versions of Windows NT 4.0 and Windows 2000, such as German, French, and Czech, a forwarder version of the msvcrt40.dll (version 4.20)is shipped. As a result, even though the DLL is linked with msvcrt40.dll and its user is linked with msvcrt.dll, you are still using the same copy of the CRT library because all calls made to msvcrt40.dll are forwarded to msvcrt.dll.
However this forwarder version of msvcrt40.dll is not available in Windows 95, Windows 98, Windows Millennium Edition (Me), and some localized versions of Windows NT 4.0 and Windows 2000, such as Japanese, Korean, and Chinese. So, if your application targets these operating systems, you need to either obtain an upgraded version of the DLL that doesn't rely on msvcrt40.dll or alter your application to not rely on using the same copy of the CRT libraries. If you have developed the DLL, this means rebuilding it with Visual C++ 4.2 or later. If it is a third- party DLL, you need to contact your vendor for an upgrade.
http://blog.sina.com.cn/s/blog_60d705b10100g4ou.html
因为malloc/free,new/delete都是调用HeapAlloc/HeapFree来实现来实现内存分配是释放的。
查看Windows的API可以看到,这两个函数都需要一个Heap的HANDLE做为参数。CRT库采用了全局变量来保存这个HANDLE。如果是CRT静态链接,CRT库的代码会链接到各个DLL中去,也包括这个全局变量。
也就是说,每个使用CRT静态链接的dll中都有一个自己的全局堆句柄,他们自己都在这个句柄上使用内存。当释放dll中分配的内存时由于使用的堆句柄不一致于是出错。