在此之前需要了解一个结构体, 它存放了你申请的内存块信息, 与上一个申请的内存块相关联的信息, 操作系统对堆内存的申请和释放都需要通过这个结构体来获取信息而这个结构体就存放在malloc所申请返回的指针上面, 而malloc申请返回的指针也是这个结构体的结束地址
原型如下:
[C] 纯文本查看 复制代码 typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;//下一个结构体指针
struct _CrtMemBlockHeader * pBlockHeaderPrev;//上一个结构体指针
char * szFileName; //文件名
int nLine; //代码行数
size_t nDataSize; //数据空间的大小(字节)
int nBlockUse; //块类型 1是自己调用 2为库函数调用 0为未调用
long lRequest; //堆申请次数
unsigned char gap[nNoMansLandSize]; //溢出标志
/* followed by:
* unsigned char data[nDataSize]; //数据空间
* unsigned char anotherGap[nNoMansLandSize]; //溢出标志
*/
} _CrtMemBlockHeader;
了解之后我们尝试着申请一个结构体, 然后到内存中看看是什么样子
申请一个结构体, 并malloc一块内存
[C] 纯文本查看 复制代码 typedef struct stStuden
{
char szName[8];
int nNum;
int nAge;
}stu;
stu * pSt = (stu *)malloc(sizeof(stu));
这时候把返回的指针拉到内存窗口, 向上拖动就可以看到这个结构体的内容
A区就是CrtMemBlockHeader结构体, 0043d108 这是下一个结构体内容 pBlockHeaderNext 00000000 因为是最后申请的结构体了, 所以为上个结构体为空 pBlockHeaderPrev 00000000 自己malloc的堆内存是没有名字和行数的, 所以为空 szFileName 00000000 参照上行 nLine 00000010 申请的堆空间大小,大小为0x10 nDataSize 01000000 块类型, 1为代码申请, 2为编译器申请, 0为释放状态 nBlockUse 00000084 堆的序号, 也是申请次数,第0x84ci申请堆空间 lRequest fdfdfdfd 溢出标志, 该位置被改变, 释放空间时会崩溃 gap[nNoMansLandSize];
B区就是所申请的内存空间 在Debug版本下, 申请的堆的可使用空间是用 ”CD” 符号填充的, “FD” 符号来防止越界, 在释放之后会使用 “EEFE” 符号来表示该区域是没有使用的区域
我们可以跟进到pBlockHeaderNext所指向的结构体中, 看看内存情况
这次可以发现pBlockHeaderPrev正好是指向我们之前申请的那块内存的_CrtMemBlockHeader的结构体头部, 这似乎很像链表
而这次nBlockUse 的值为02 , 这是一个库函数malloc的一块内存, 并且名字和行数的指针有了数据
申请的大小为0x3e, 是第0x83次申请, 通过跟上图对比我们可以了解到很多信息
了解完这些信息就可以试试代码遍历现在的堆了, 通过pBlockHeaderNext访问相邻的结构体, 通过来判断是否为空为结束, 以此来作为条件循环读取每个结构体的信息
代码如下:
[C] 纯文本查看 复制代码 _CrtMemBlockHeader *pHead = (_CrtMemBlockHeader*)pSt - 1;//获取结构体指针位置
while (pHead != NULL)
{
printf("szFileName:%s nLine:%d nDataSize:%d nBlockUse:%d "
"lRequest:%d stAdddress:%p DataAdddress:%p\r\n",
pHead->szFileName,
pHead->nLine,
pHead->nDataSize,
pHead->nBlockUse,
pHead->lRequest,
pHead,
pHead + 1);//指针+1等于加上指针类型的大小
pHead = pHead->pBlockHeaderNext; //把下一个结构体指针给pHead
}
//释放
if (pSt != NULL)
{
free(pSt);
pSt = NULL;
}
运行结果:
可以清楚的看到现在程序中堆的情况
PS: stdenvp这货申请那么多空间是干什么的啊= =
好了, 大概就是这些, 文中大部分都是写的都是自己的理解, 并不是官方解释, 如有错误请大家指出 谢谢了~~
|