现在的位置: 首页 > 综合 > 正文

浅析CRT–Debug模式下的内存管理(翻译 作者:Marius Bancila )

2013年05月04日 ⁄ 综合 ⁄ 共 2187字 ⁄ 字号 评论关闭
  • 前言:
  • 当你编译处于Debug模式下的Visual Studio的程序时候,你会发现申请或销毁的内存具有奇怪的值,比如:0xCDCDCDCD或者0xDDDDDDDD.这是为在Win32平台下对内存的保护,防止泄露的措施。在这里,我将介绍完成内存的申请和销毁的new/delete和malloc/free.    
  •  
  • 首先,我将解释这些奇怪的值,如CD,DD等等值   
  • 名字      描述
  • 0xCD   Clean Memory    申请的内存由malloc或者new完成
  • 0xDD   Dead Memory    释放后的内存,用来检测悬垂指针
  • 0xFD   Fence Memory    动态申请后的内存值,没有初始化。用来检测数组的下标界限
  • 0xAB   (Allocated Block?)    使用LocalAlloc()分配的内存 0x0DF0ADBA  Bad Food     使用LocalAlloc并且参数为LMEM_FIXED,但是还没写入
  • 0xCC    使用了/GZ选项,没有初始化的自动变量在DBGHEAP.C文件中,
  •  
  • 有如下的定义:
  • static unsigned char _bNoMansLandFill = 0xFD;   /* fill no-man's land with this */  
  • static unsigned char _bDeadLandFill   = 0xDD;   /* fill free objects with this */static unsigned char _bCleanLandFill  = 0xCD;   /* fill new objects with this */
  •  
  • Function    Description
  • malloc    C/C++ 使用来申请内存空间,在C++中操作符new是在malloc的基础上被重载的_malloc_dbg   只有在Debug模式下才有效
  • free    C/C++ 用来释放内存空间,在C++中操作符delete是在free的基础上被重载的_free_dbg   只有在Debug模式下才有效
  • LocalAlloc  Win32 API,Windows内存管理器不会提供本地和全不堆LocalFree   Win32 API释放内存对象的句柄
  • HeapAlloc   Win32 APIHeapFree   Win32 API
  • 例子:
  • int main(int argc, char* argv[])
  • {  
  • char *buffer = new char[12];   
  • delete [] buffer;   
  • return 0;
  • }
  • 这里,12Byte是动态获取的,但是CRT内存分配器还要添些预定信息,所以每块CRT信息都保存_CrtMemBlockHeader,在DBGINT.h中定义#define nNoMansLandSize 4 typedef struct _CrtMemBlockHeader
  • {       
  •  struct _CrtMemBlockHeader * pBlockHeaderNext;       
  •  struct _CrtMemBlockHeader * pBlockHeaderPrev;       
  •  char *                      szFileName;       
  •  int                         nLine;       
  • size_t                      nDataSize;       
  • int                         nBlockUse;      
  •   long                        lRequest;       
  • unsigned char               gap[nNoMansLandSize];        /* followed by:         *  unsigned char           data[nDataSize];         *  unsigned char           anotherGap[nNoMansLandSize];         */
  • }
  •  _CrtMemBlockHeader;
  • 简单介绍:
  • pBlockHeaderNext  一个指向下个申请内存的指针
  • pBlockHeaderPrev  一个指向前个申请内存的指针
  • szFileName  一个指向申请内存后创建文件的名字指针
  • nDataSize 文件大小
  • nBlockUse  0 - free后的区域,但是还没归还给Win32内存管理器
                          1 - 正常区域(从new/malloc申请)
                          2 - CRT 区域, 由CRT申请并自己使用
    lRequest 每个申请区域增大的数量
    gap 由0XFD填充的4byte区域

大多数堆管理区域是由HeapAlloc()和HeapFree来完成,当你申请12bytes 的内存区域时,malloc调用HeapAlloc来申请36或更多的内存,然后malloc填充_CrtMemBlockHeader并初始化为0XCD和不能使用的0XFD.

 

后记:很久没来写Blog了,今天心血来潮,把我第一篇翻译的文章献出来(可能出丑了~)。作者文章解释了很多平时编程在Visual Studio IDE时遇到不明白的地方。希望对你也有用。

抱歉!评论已关闭.