尽管malloc和free所提供的内存分配接口比之brk和sbrk要容易许多,但在使用时仍然容易犯下各种编程错误。

理解malloc和free的实现,将使我们洞悉产生这些错误的原因以及如何才能避免此类错误。

to be continued 。。。。。。

malloc的实现很简单。

它首先会扫描之前由free所释放的空闲内存列表,以求找到尺寸大于或等于要求的一块空闲内存。

(这取决于具体实现,采用的扫描策略会有所不同。例如first-fit或best-fit。)

如果这一内存块的尺寸正好与要求相当,就把它直接返回给调用者。如果是一块较大的内存,那么将对其进行分割,在将一块大小相同的内存返回给调用者的同时,把较小的那块空闲内存块保留在空闲列表中。

如果在空闲内存列表中根本找不到足够大的空闲内存块,那么malloc会调用sbrk以分配更多的内存。为减少对sbrk的调用次数,malloc并未只是严格按所需字节数来分配内存,而是以更大幅度(以虚拟内存页大小的数倍)来增加prgram break,并将超出部分置于空闲内存列表。

至于free函数的实现则更为有趣。

当free将内存块置于空闲列表之上使,是如何知晓内存块大小的?

这是通过一个小技巧来实现的。

当malloc分配内存块时,会额外分配几个字节来存放记录这块内存大小的整数值。该整数位于内存块 的起始处,而实际返回给调用者的内存地址恰好位于这一长度记录字节之后,如下图所示。

当将内存块置于空闲内存列表(双向链表)时,free会使用内存块本身的空间来存放链表指针,将自身添加到列表中,如下图

随着内存不断地释放和重新分配,空闲列表中的空闲内存和已分配的在用内存混杂在一起,如下图

应该认识到,C语言允许程序创建指向堆中任意位置的指针,并修改其指向的数据,包括由free和malloc维护的内存块长度、指向前一空闲块和后一空闲块的指针。辅之以之前的描述,一旦推究起隐晦难解的编程缺陷来,这无疑形同掉进了火药桶。

例如,假设经由一个错误指针,程序无意间增加了冠于一块已分配内存的长度值,并随即释放这块内存,free因之会在空闲列表记录下这块长度失真的内存。

随后,malloc也许会重新分配这块内存,从而导致如下场景:程序的两个指针分别指向两块它认为互不相干的已分配内存,但实际上这块内存缺相互重叠。

至于其他出错情况则数不胜数。

要避免这类错误,应该遵守一下原则。

Unix系统编程()malloc和free的实现的更多相关文章

  1. 《Linux/Unix系统编程手册》读书笔记4

    <Linux/Unix系统编程手册>读书笔记 目录 第7章: 内存分配 通过增加堆的大小分配内存,通过提升program break位置的高度来分配内存. 基本学过C语言的都用过mallo ...

  2. 《Linux/Unix系统编程手册》读书笔记3

    <Linux/Unix系统编程手册>读书笔记 目录 第6章 这章讲进程.虚拟内存和环境变量等. 进程是一个可执行程序的实例.一个程序可以创建很多进程. 进程是由内核定义的抽象实体,内核为此 ...

  3. 《Linux/Unix系统编程手册》 时间子系统

    Linux下操作系统编程有两本经典APUE即<Advanced Programming in the UNIX Environment>和TLPI<The Linux Program ...

  4. 《Linux/Unix系统编程手册》读书笔记 目录

    <Linux/Unix系统编程手册>读书笔记1  (创建于4月3日,最后更新4月7日) <Linux/Unix系统编程手册>读书笔记2  (创建于4月9日,最后更新4月10日) ...

  5. 《Linux/Unix系统编程手册》读书笔记9(文件属性)

    <Linux/Unix系统编程手册>读书笔记 目录 在Linux里,万物皆文件.所以文件系统在Linux系统占有重要的地位.本文主要介绍的是文件的属性,只是稍微提及一下文件系统,日后如果有 ...

  6. 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

    <Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...

  7. 《Linux/Unix系统编程手册》读书笔记7 (/proc文件的简介和运用)

    <Linux/Unix系统编程手册>读书笔记 目录 第11章 这章主要讲了关于Linux和UNIX的系统资源的限制. 关于限制都存在一个最小值,这些最小值为<limits.h> ...

  8. 《Linux/Unix系统编程手册》读书笔记6

    <Linux/Unix系统编程手册>读书笔记 目录 第9章 这章主要讲了一堆关于进程的ID.实际用户(组)ID.有效用户(组)ID.保存设置用户(组)ID.文件系统用户(组)ID.和辅助组 ...

  9. 《Linux/Unix系统编程手册》读书笔记5

    <Linux/Unix系统编程手册>读书笔记 目录 第8章 本章讲了用户和组,还有记录用户的密码文件/etc/passwd,shadow密码文件/etc/shadow还有组文件/etc/g ...

  10. 《Linux/Unix系统编程手册》读书笔记1

    <Linux/Unix系统编程手册>读书笔记 目录 最近这一个月在看<Linux/Unix系统编程手册>,在学习关于Linux的系统编程.之前学习Linux的时候就打算写关于L ...

随机推荐

  1. C++实现委托机制(二)

    1.引言: 上一篇文章已经介绍了如何构建一个无参数无返回值的函数指针的委托,这篇文章将对上一文章所述委托进行扩展,使得可以注册任意函数指针,不过再讲篇内容之前先要介绍一下实现这个功能所需要了解的C++ ...

  2. MIME简介

    MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型.是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器 ...

  3. 浏览器自动化测试初探 - 使用phantomjs与casperjs

    收录待用,修改转载已取得腾讯云授权 作者:yangchunwen 首先要解释一下为什么叫浏览器自动化测试,因为本文只关注发布后页面功能的自动化测试,也就是UI层面的自动化. 浏览器测试有别于js代码的 ...

  4. Javaee项目经验须知

    Java的主要应用领域就是企业级的项目开发!具体要点(09年,那一年我去面试,被拒了几次,想起来还不错!他锻炼了我的心理素质,让我体会到很多,笑一个吧!): 1.掌握项目开发的基本步骤 2.具备极强的 ...

  5. wifidog 移植到MIPS平台

    使用的是一款Broadcom的芯片,现在上面运行wifidog实现认证上网的功能.由于不是openwrt平台,所以就没了make menuconfig 勾选就能自动编译到版本中的.所以想使用交叉编译的 ...

  6. PHPNOW如何添加虚拟主机

    1 打开PHPNow控制面板,输入0,点回车 2 新增主机名称(你可以输入127.0.0.2到127.0.0.255),点击回车之后要求输入主机别名,不要写,直接回车,再要求输入网站目录,也不选,再回 ...

  7. ionic的加载功能

    下面是代码(黄色背景的是加载功能的代码): <html ng-app="ionicApp"> <head> <meta charset="u ...

  8. 导入exce表格中的数据l到数据库

    因为我的项目是JavaWeb的,所有是通过浏览器导入数据库到服务器端的数据库,这里我们采用struts来帮助我们完成. 1:首先定义一个文件上传的jsp页面.把我们的数据先上传到服务器端. <f ...

  9. synthesis-of-weak-property-only-allowed-in-arc-or-gc-mode ARC属性

    synthesis-of-weak-property-only-allowed-in-arc-or-gc-mode ARC属性 错误提示: 1:确认你的项目是 ARC环境: 2:如果 ARC下出现上面 ...

  10. Shodan:黑客的物联网搜索引擎

    记得看过一个电影.里面的科学家开发了一个超级系统,能够实时监控全部可用摄像头.让逃犯无处遁形. Shodan这个新型的搜索引擎可能会让这个想法变成现实. 和Google这些传统互联网信息搜索引擎不同. ...