Unix系统编程()malloc和free的实现
尽管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的实现的更多相关文章
- 《Linux/Unix系统编程手册》读书笔记4
<Linux/Unix系统编程手册>读书笔记 目录 第7章: 内存分配 通过增加堆的大小分配内存,通过提升program break位置的高度来分配内存. 基本学过C语言的都用过mallo ...
- 《Linux/Unix系统编程手册》读书笔记3
<Linux/Unix系统编程手册>读书笔记 目录 第6章 这章讲进程.虚拟内存和环境变量等. 进程是一个可执行程序的实例.一个程序可以创建很多进程. 进程是由内核定义的抽象实体,内核为此 ...
- 《Linux/Unix系统编程手册》 时间子系统
Linux下操作系统编程有两本经典APUE即<Advanced Programming in the UNIX Environment>和TLPI<The Linux Program ...
- 《Linux/Unix系统编程手册》读书笔记 目录
<Linux/Unix系统编程手册>读书笔记1 (创建于4月3日,最后更新4月7日) <Linux/Unix系统编程手册>读书笔记2 (创建于4月9日,最后更新4月10日) ...
- 《Linux/Unix系统编程手册》读书笔记9(文件属性)
<Linux/Unix系统编程手册>读书笔记 目录 在Linux里,万物皆文件.所以文件系统在Linux系统占有重要的地位.本文主要介绍的是文件的属性,只是稍微提及一下文件系统,日后如果有 ...
- 《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)
<Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候 ...
- 《Linux/Unix系统编程手册》读书笔记7 (/proc文件的简介和运用)
<Linux/Unix系统编程手册>读书笔记 目录 第11章 这章主要讲了关于Linux和UNIX的系统资源的限制. 关于限制都存在一个最小值,这些最小值为<limits.h> ...
- 《Linux/Unix系统编程手册》读书笔记6
<Linux/Unix系统编程手册>读书笔记 目录 第9章 这章主要讲了一堆关于进程的ID.实际用户(组)ID.有效用户(组)ID.保存设置用户(组)ID.文件系统用户(组)ID.和辅助组 ...
- 《Linux/Unix系统编程手册》读书笔记5
<Linux/Unix系统编程手册>读书笔记 目录 第8章 本章讲了用户和组,还有记录用户的密码文件/etc/passwd,shadow密码文件/etc/shadow还有组文件/etc/g ...
- 《Linux/Unix系统编程手册》读书笔记1
<Linux/Unix系统编程手册>读书笔记 目录 最近这一个月在看<Linux/Unix系统编程手册>,在学习关于Linux的系统编程.之前学习Linux的时候就打算写关于L ...
随机推荐
- 转:美团Android资源混淆保护实践
转自:http://tech.meituan.com/mt-android-resource-obfuscation.html 前言 Android应用中的APK安全性一直遭人诟病,市面上充斥着各种被 ...
- 【Hibernate一】概述及入门
Hibernate学习框架: 1.基本部分 crud的操作 主键的生成机制 类型 持久化类 映射文件 *.hbm.xml 配置文件 hibe ...
- 随机数的生成:给定1-n的随机数生成器randn(),生成1-m的随机数
1.当m < n时比较简单: 只当randn()生成的数落在1-m上时,就输出,否则继续生成: 2.当m > n时就比较麻烦一点, 基本思路还是和第一种情况是一样的,问题是怎样才能利用ra ...
- 算法笔记_038:特殊回文数(Java)
目录 1 问题描述 2 解决方案 2.1 80分解法 2.2 网友标答解法 1 问题描述 问题描述 123321是一个非常特殊的数,它从左边读和从右边读是一样的. 输入一个正整数n, 编程求所有这 ...
- javascript 自定义动画函数
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...
- ajax调用webservice服务
ajax调用是 html方向调用的, 而sqlconnection是 java代码调用的,本质差不多 <html> <head> <title>通过ajax调用we ...
- 【转帖】如何利用Spring Cloud构建起自我修复型分布式系统
http://zhidao.baidu.com/link?url=tSKwdn3wr8KUxWMteHmneFtY0KoNZBMK9Xy-RimsdISA4h2neAecgHqggBipz2w6nXr ...
- Oracle常用单行函数(原创)
前言: 想把单行函数进行一个比较全面的总结,并分享给有需要的人,有不明之处还请多多指教. SQL函数:Oracle的内置函数,包括了单行函数和多行函数,本文重点讲解单行函数.单行函数又可以分为许多类, ...
- Redis总结(四)Redis 的持久化(转载)
前面已经总结了Redis 的安装和使用今天讲下Redis 的持久化. redis跟memcached类似,都是内存数据库,不过redis支持数据持久化,也就是说redis可以将内存中的数据同步到磁盘来 ...
- 类模板、Stack的类模板实现(自定义链栈方式,自定义数组方式)
一.类模板 类模板:将类定义中的数据类型参数化 类模板实际上是函数模板的推广,可以用相同的类模板来组建任意类型的对象集合 (一).类模板的定义 template <类型形参表> clas ...