吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5185|回复: 8
收起左侧

[原创] C语言malloc的内存在堆中存放与管理

  [复制链接]
StriveMario 发表于 2016-9-27 22:59
在此之前需要了解一个结构体, 它存放了你申请的内存块信息, 与上一个申请的内存块相关联的信息, 操作系统对堆内存的申请和释放都需要通过这个结构体来获取信息而这个结构体就存放在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这货申请那么多空间是干什么的啊= =

好了, 大概就是这些,  文中大部分都是写的都是自己的理解, 并不是官方解释, 如有错误请大家指出 谢谢了~~





免费评分

参与人数 2热心值 +2 收起 理由
Hmily + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
44018723 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

没图你说个图 发表于 2016-9-27 23:16
程序运行当然要申请空间
展鸿 发表于 2016-9-27 23:29
stdenvp设置了一个全局二维数组,用来保存环境变量值。
 楼主| StriveMario 发表于 2016-9-27 23:30
展鸿 发表于 2016-9-27 23:29
stdenvp设置了一个全局二维数组,用来保存环境变量值。

  谢谢...学习了
Hymn 发表于 2016-9-28 00:57
好东西,感谢楼主。我要学习学习
zhashia 发表于 2016-9-28 01:40 来自手机
复杂啊,只知道用malloc不知道原理
MAXtoDEATH 发表于 2016-9-28 10:40
手持两把锟斤拷,口中疾呼烫烫烫
脚踏千朵屯屯屯,笑看万物锘锘锘
yeyulang 发表于 2016-9-28 17:35
虽然看不懂..不过努力学习!
caroot1996 发表于 2016-9-28 23:25
第一次看到malloc的原理,楼主666
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-17 10:45

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表