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

本文深入解析Visual Studio在Debug模式下的内存管理机制,包括特殊值的意义(如0xCD、0xDD等),以及malloc/new与free/delete如何工作。通过具体示例说明了_CrtMemBlockHeader的结构及其作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 前言:
  • 当你编译处于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时遇到不明白的地方。希望对你也有用。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值