20. 堆信息块头
内存空间大致分为:
code |
data |
stack |
heap |
4个和堆相关的Windows Api:
HeapCreate
HeapAlloc
HeapFree
HeapDestroy
vc6中已分配的堆内存初始字节是0xCDCD(屯);未分配的堆内存字节是0xFEEE(铪)或0xDDDD(葺)
_malloc_dbg可以提供源代码所在文件名,调用的行号等信息,且在数据两侧各有4字节缓冲区,用来检测程序员是否越界读写。
实际编程时注意数据隐藏,不要将敏感信息暴露出去,例如定义成如下形式,只在debug版本中出现敏感信息:
#ifdef _DEBUG
#define malloc(size) _malloc_dbg(size, _NORMAL_BLOCK, __FILE__, __LINE__)
#endif // _DEBUG
使用以上宏调:void *p = malloc(16);
p保存了申请的地址0x00448718,此地址减去0x20,得到堆结构头部的地址。
下图中每个红色方框代表的含义写在右侧监视窗口里
vc6中分配大小在块类型前面
据此定义一个结构体:
struct Head {
Head *prev; //prev等于0代表第一个
Head *next; //next等于0代表最后一个
const char *fileName;
size_t lineNumber;
size_t blockType;
size_t dataSize;
size_t AllocNumber; //不一定连续,有的内存可能被释放了
size_t overflowBuff;
unsigned char data[1];
//size_t underflowBuff;
};
遍历即可得到所有申请的堆内存信息。
参考https://docs.microsoft.com/zh-cn/visualstudio/debugger/crt-debug-heap-details?view=vs-2019