以下是一段简单的C代码,malloc和free到底做了什么?

  1. int main()
  2. {
  3. char* p = (char*)malloc(32);
  4. free(p);
  5. return 0;
  6. }

malloc和free的debug和release版本实现各不相同,而且相差很大。

Debug版本

malloc需要分配的内存会比实际的size多36byte。最终分配的内存块如下:
 
 
_CrtMemBlockHeader是一个双向链表结构,其定义如下:
  1. <pre name="code" class="cpp">typedef struct _CrtMemBlockHeader
  2. {
  3. struct _CrtMemBlockHeader *pBlockHeaderNext;    //下次分配的内存块
  4. struct _CrtMemBlockHeader *pBlockHeaderPrev;    //上次分配的内存块
  5. char *szFileName;               //分配内存代码的文件名
  6. int nLine;                  //分配内存代码的行号
  7. size_t nDataSize;               //请求的大小,如实例中的32
  8. int nBlockUse;                  //请求的内存类型,如实例中的user类型
  9. long lRequest;                  //请求id,每次请求都会被记录
  10. unsigned char gap[nNoMansLandSize];     //4字节校验位
  11. } _CrtMemBlockHeader;

 
用户请求内存前后分别有4字节的校验位,分配内存后都会被初始化为0xFD。如果这8个字节被改写,free时就会触发断言失败。
而请求的32字节会被初始化为0xCC(和栈的初始化一样)。
系统通过记录这些信息就能显示的给出错误。比如越界访问请求的内存在debug下会断言失败,release下面则不会,从而这会给程序埋下巨大的隐患。很多在release下偶发的错误就是这样产生的。
_CrtMemBlockHeader总共32字节,加上用户请求的32字节及最后4字节校验位是68字节。最终调用系统的API请求内存。比如Windows下面是HeapAlloc。
 
如果内存分配失败,malloc不像new那样可以调用new_handler来处理,它直接返回NULL。
 
free则是对_CrtMemBlockHeader的信息做清理操作,检查校验位等等。最终调用系统API释放内存。比如Windows下面是HeapFree。
 

Release版本

实际分配的内存等于请求的内存大小。malloc和free只是在系统API之上做了些判断操作。
 

总结

C语言是跨平台的,最终的内存处理都是交给系统API完成。系统会记录每一块分配内存的地址,大小,释放情况等等。所以free时只需要传一个地址的参数就可以了。而且同一个地址不能释放两次。

http://blog.csdn.net/passion_wu128/article/details/38964045

C语言malloc和free实现原理的更多相关文章

  1. Go语言数组和切片的原理

    目录 数组 创建 访问和赋值 切片 结构 初始化 访问 追加 拷贝 总结 数组和切片是 Go 语言中常见的数据结构,很多刚刚使用 Go 的开发者往往会混淆这两个概念,数组作为最常见的集合在编程语言中是 ...

  2. C语言与汇编语言相互调用原理以及实例

    C语言与汇编语言相互调用原理以及实例 1.原理 其实不管是C语言还是汇编语言想要执行都是最终编译链接成为二进制文件. 这里一定要明确编译和链接是两个步骤,生成的文件格式也是不一样的. 编译生成的文件是 ...

  3. atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97

    atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97 1. 实现html5化界面的要解决的策略1 1.1. Js交互1 1.2. 动态参 ...

  4. 15、R语言聚类树的绘图原理

    聚类广泛用于数据分析.去年研究了一下R语言聚类树的绘图原理.以芯片分析为例,我们来给一些样品做聚类分析.聚类的方法有很多种,我们选择Pearson距离.ward方法. 选择的样品有: "GS ...

  5. 浅谈malloc()和free()工作原理

    编程之路刚刚开始,错误难免,希望大家能够指出.  malloc()和free()是我经常需要用到的函数,一般情况下,C程序使用malloc()在堆上分配内存,free()释放内存,两者的参数和返回值就 ...

  6. C语言可变参数函数实现原理

    一.可变参数函数实现原理 C函数调用的栈结构: 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 本 ...

  7. C语言malloc()函数:动态分配内存空间

    头文件:#include <stdlib.h> malloc() 函数用来动态地分配内存空间(如果你不了解动态内存分配,请查看:C语言动态内存分配及变量存储类别),其原型为:void* m ...

  8. (转)C语言malloc()与free()的使用

    如何使用 malloc 函数 本文为转载内容,原文地址请点击 不要莫名其妙,其实上面这段小小的对话,就是malloc的使用过程.malloc是一个函数,专门用来从堆上分配内存.使用malloc函数需要 ...

  9. Go语言备忘录:反射的原理与使用详解

    目录: 预备知识 reflect.Typeof.reflect.ValueOf Value.Type 动态调用 通过反射可以修改原对象 实现类似“泛型”的功能   1.预备知识: Go的变量都是静态类 ...

随机推荐

  1. SQL Server中in与exist效率比较

    in和exists in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询. 一直以来认为exists比in效率高的说法是不准确的. 如果查询的两 ...

  2. QT中嵌入SDL

    原地址:http://www.qtcn.org/bbs/read.php?tid=23926 前段时间在做一个音视频编码板卡的PC跨平台程序,使用QT框架,其中有块功能是往QT里嵌入SDL,来播放YU ...

  3. Hadoop--Hadoop的机架感知

    Hadoop的机架感知 Hadoop有一个“机架感知”特性.管理员可以手工定义每个slave数据节点的机架号.为什么要做这么麻烦的事情?有两个原因:防止数据丢失和提高网络性能.     为了防止数据丢 ...

  4. cdoj 491 Tricks in Bits

    //无脑爆居然能过!!!!! 解:其实正解也是暴力,但是可以证明在n>6时答案一定为零. 第一步:对于任意两个数他们的二进制数要么有一半+的位是相同的,要么有一半+的位是不同的,于是首先使用与运 ...

  5. POJ 1734 求最小环路径 拓展Floyd

    九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/11888019 题意: n个点 m条无向边 下面m条有权无向边 问图中最小环的路径 ...

  6. 【ThinkPHP学习】ThinkPHP自己主动转义存储富文本编辑器内容导致读取出错

    RT. ThinkPHP的conf文件里的Convention.php有一个配置选项 'DEFAULT_FILTER' => 'htmlspecialchars', // 默认參数过滤方法 用于 ...

  7. windows7旗舰版64位下安装、破解及执行QTP11报错

    说明:假设你出现了下面几种情况,希望能解决你的问题:假设没有,就当路过. 1.安装qtp11时报vc++ 2005缺少,但怎么也不能安装成功 解决方法: 1.找到qtp安装包里面的vc++ 2005组 ...

  8. hibernate 之 HQL语句总结【转】

    1. 查询整个映射对象所有字段 //直接from查询出来的是一个映射对象,即:查询整个映射对象所有字段 String hql = "from Users"; Query query ...

  9. oracle系统参数修改

    create pfile='/home/oracle/sss.ora' from spfile; create spfile from pfile='/home/oracle/sss.ora'; al ...

  10. 记一次dedeCMS网站搭建全过程

    Step 1 使用阿里云Windows Server 2012服务器 { 使用远程桌面进行操作,ip admin pwd登录 } Step 2 下载安装phpStudy包 { 下载安装,直接安装到C盘 ...