首页
社区
课程
招聘
[原创]VC++6调试状态下的堆结构
发表于: 2024-8-28 09:01 4688

[原创]VC++6调试状态下的堆结构

2024-8-28 09:01
4688

C语言标准对堆内存的申请提供了三个函数:

释放堆内存提供一个函数:

C标准函数落地到具体的操作系统,需要系统调用,Windows提供了如下5个系统调用:

在VC++平台,除了C标准库函数,还提供了相对应的调试版函数:

先准备一段C代码:

在VC++6中,main函数是由mainCRTStartup函数调用的,可以通过栈帧窗口定位到该函数,然后在堆初始化处打一个断点:


步入_heap_init方法,这里调用了系统调用HeapCreate:


单步往下执行,可以看到有调用HeapDestroy的地方,不过该分支并没有执行到:


在main函数中调用malloc的地方打断点:

层层步入:



最终执行到这里,调用了HeapAlloc系统调用:


接下来跟进calloc函数:


步入_calloc_dbg,这里将入参nSize和nNum相乘并将乘积赋值给nSize,并且再用nSize调用_malloc_dbg:


继续跟进的话,发现最终也调用了HeapAlloc:


再跟进realloc函数:


最终调用了HeapReAlloc:


最后跟进free函数:

最终调用了HeapFree:


在main函数返回后,会调用exit函数结束进程,exit最终会跟进到一个ExitProcess调用,里面会调用HeapDestroy销毁堆,但由于这是一个系统函数,所以无法步入。


总结:

进程启动时调用HeapCreate创建堆;

malloc底层调用了HeapAlloc;

calloc先计算num*size,再调用malloc;

realloc底层调用了HeapReAlloc;

free底层调用了HeapFree;

进程退出时,调用HeapDestroy。


VC++平台提供的调试版函数可以在堆内存中添加更多附加信息,方便调试,所以我们在代码中定义几个宏:

这样在使用C标准函数时会替换为调试版函数,以_malloc_dbg为例解释入参含义:

size 申请堆内存的字节数


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2024-8-28 09:20 被米龙·0xFFFE编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 8805
活跃值: (5296)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
处处留心皆学问,学习了。
2024-8-28 09:36
1
游客
登录 | 注册 方可回帖
返回
//