调试堆中的块类型
本主题适用于:
版本 |
Visual Basic |
C# |
F# |
C++ |
Web Developer |
---|---|---|---|---|---|
学习版 |
仅限本机 |
||||
专业版、高级专业版和旗舰版 |
仅限本机 |
调试堆中的每个内存块都分配以五种分配类型之一。 出于泄漏检测和状态报告目的对这些类型进行不同地跟踪和报告。 可以指定块的类型,方法是使用对其中一个调试堆分配函数(如 _malloc_dbg)的直接调用来分配块。 调试堆中的五种内存块类型(在 _CrtMemBlockHeader 结构的 nBlockUse 成员中设置)如下所示:
_NORMAL_BLOCK
对 malloc 或 calloc 的调用将创建“普通”块。 如果打算只使用“普通”块而不需要“客户端”块,则可能想要定义 _CRTDBG_MAP_ALLOC,它导致所有堆分配调用映射到它们在“Debug”版本中的调试等效项。 这将允许将关于每个分配调用的文件名和行号信息存储到对应的块头中。_CRT_BLOCK
由许多运行库函数内部分配的内存块被标记为 CRT 块,以便可以单独处理这些块。 结果,泄漏检测和其他操作不需要受这些块影响。 分配永不可以分配、重新分配或释放任何 CRT 类型的块。_CLIENT_BLOCK
出于调试目的,应用程序可以专门跟踪一组给定的分配,方法是使用对调试堆函数的显式调用将它们作为该类型的内存块进行分配。 例如,MFC 以“客户端”块类型分配所有的 CObjects;其他应用程序则可能在“客户端”块中保留不同的内存对象。 还可以指定“客户端”块的子类型以获得更大的跟踪粒度。 若要指定“客户端”块子类型,请将该数字向左移 16 位,并将它与 _CLIENT_BLOCK 进行 OR 运算。 例如:#define MYSUBTYPE 4 freedbg(pbData, _CLIENT_BLOCK|(MYSUBTYPE<<16));
客户端提供的挂钩函数(用于转储在“客户端”块中存储的对象)可以使用 _CrtSetDumpClient 进行安装,然后,每当调试函数转储“客户端”块时均会调用该挂钩函数。 同样,对于调试堆中的每个“客户端”块,可以使用 _CrtDoForAllClientObjects 来调用应用程序提供的给定函数。
_FREE_BLOCK
通常,所释放的块将从列表中移除。 为了检查并未仍在向已释放的内存写入数据,或为了模拟内存不足情况,可以选择在链接列表上保留已释放块,将其标记为“可用”,并用已知字节值(当前为 0xDD)填充。_IGNORE_BLOCK
有可能在一段时间内关闭调试堆操作。 在该时间段内,内存块保留在列表上,但被标记为“忽略”块。
若要确定给定块的类型和子类型,请使用 _CrtReportBlockType 函数以及 _BLOCK_TYPE 和 _BLOCK_SUBTYPE 宏。 宏的定义(在 crtdbg.h 中)如下所示:
#define _BLOCK_TYPE(block) (block & 0xFFFF)
#define _BLOCK_SUBTYPE(block) (block >> 16 & 0xFFFF)