zoukankan      html  css  js  c++  java
  • 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中分配的内存时由于使用的堆句柄不一致于是出错。

  • 相关阅读:
    new对象数组时的内存布局
    写程序取自己进程的AEP
    类虚函数表原理实现分析(当我们将虚表地址[n]中的函数替换,那么虚函数的实现就由我们来控制了)
    测试 __try, __finally, __except(被__finally捕获的异常, 还会被上一级的__except捕获。反之不行)
    围观M$的new
    将258.369 double值转为内存表示(科学计数法)
    Broadcast Reveiver作用
    DEBUG模式下, 内存中的变量地址分析
    不包含SDK头文件, 补全API定义
    俄罗斯方块SDK版
  • 原文地址:https://www.cnblogs.com/europelee/p/3388660.html
Copyright © 2011-2022 走看看