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

第7章:

内存分配

通过增加堆的大小分配内存,通过提升program break位置的高度来分配内存。

基本学过C语言的都用过malloc来分配内存,而malloc都基于brk()和sbrk()。

 #include <unistd.h>

 int brk(void *end_data_segment);

 int *sbrk(intptr_t increment);

brk()系统调用会将program break设置为end_data_segment的位置。成功调用返回0,失败返回-1。

sbrk()系统调用会将program break原来的位置增加increment的大小。成功调用返回原来program break的位置,失败返回(void *)-1。

PS:sbrk(0)返回program break的当前位置。

malloc()函数,C使用该函数在堆上分配和释放内存。

 #include <stdlib.h>

 void *malloc(size_t size);

malloc分配size字节大小的内存。并返回指向新分配的内存的起始位置的指针,该内存未经初始化;失败返回NULL。

通常对返回的指针进行显式类型转换来获得自己想要的类型的指针。

实际上每次调用malloc分配内存时,会额外分配多几个字节来记录这块内存的大小。(如下图所示)

free()函数用来释放内存块。

 #include <stdlib.h>

 void free(void *ptr);

free释放ptr指向的内存块,ptr必须是malloc、calloc、realloc返回的指针。

free不会降低program break的位置,而是将该内存添加到空闲内存列表,用于以后malloc使用。

PS:不能对已经调用过free函数的指针,再次调用free,这样会产生错误。

因为malloc分配后的内存会有内存块的长度,所以free会知道这块内存的大小,从而准确的将内存块释放,并放入空闲内存块列表中。

PS:因此不能用free随便释放不是malloc返回的指针。

经过free释放后的内存块结构如下:

其实malloc调用是先查找空闲内存块列表,找到合适的内存块。如果找不到合适的内存块就调用sbrk()来分配更多的内存,为了减少调用sbrk的次数,会分配比size大小更多的内存来增加program break的位置,超出size大小的内存块会放到空闲内存列表。

calloc()函数可以对一组相同的对象分配内存。

#include <stdlib.h>

void *calloc(size_t numitems, size_t size);

numitems指定了对象的数量,size指定了每个对象的大小。成功调用返回内存块的起始地址,失败返回NULL。malloc返回的内存不会初始化,而calloc返回的内存块是已初始化。

realloc()函数可以调整一块内存的大小。

 #include <stdlib.h>

 void *realloc(void *ptr, size_t size);

ptr是需要调整大小的内存块的指针, size是所需调整大小的期望值。

成功调用会返回指向调整后内存块的指针(位置可能不同),失败返回NULL。

练习:

7-1. 修改程序清单7-1中的程序,在每次执行malloc()后打印出program break的当前至。指定一个较小的内存分配尺寸来运行该程序。这将证明malloc不会在每次调用时都会调用sbrk()来调整program break的位置,而是周期性地分大块内存,并从中将小片内存返回给调用者。

程序清单7-1:

 /*
* =====================================================================================
*
* Filename: free_and_sbrk.c
*
* Description:
*
* Version: 1.0
* Created: 2014年03月19日 11时37分09秒
* Revision: none
* Compiler: gcc
*
* Author: alan (), alan19920626@gmail.com
* Organization:
*
* =====================================================================================
*/ #include "tlpi_hdr.h" #define MAX_ALLOCS 1000000 int main(int argc, char *argv[]){
char *ptr[MAX_ALLOCS];
int freeStep, freeMin, freeMax, blockSize, numAllocs, j; printf("\n"); if(argc < || strcmp(argv[], "--help") == )
usageErr("%s num-allocs blocksize [step [min [max]]]\n", argv[]); numAllocs = getInt(argv[], GN_GT_0, "num-allocs"); if(numAllocs > MAX_ALLOCS)
cmdLineErr("num-allocs > %d\n", MAX_ALLOCS); blockSize = getInt(argv[], GN_GT_0 | GN_ANY_BASE, "blocksize"); freeStep = (argc > ) ? getInt(argv[], GN_GT_0, "step") : ;
freeMin = (argc > ) ? getInt(argv[], GN_GT_0, "min") : ;
freeMax = (argc > ) ? getInt(argv[], GN_GT_0, "max") : numAllocs; if(freeMax > numAllocs)
cmdLineErr("free-max > num-allocs\n"); printf("Initial program break: %10p\n", sbrk()); printf("Allocing %d*%d bytes\n", numAllocs, blockSize); for(j = ; j < numAllocs; j++){
ptr[j] = malloc(blockSize);
if(ptr[j] == NULL)
errExit("malloc");
} printf("Program break is now: %10p\n", sbrk()); printf("Freeing blocks from %d to %d in steps of %d\n", freeMin, freeMax, freeStep);
for(j = freeMin-; j < freeMax; j += freeStep)
free(ptr[j]); printf("After free(), program break is %10p\n", sbrk()); exit(EXIT_SUCCESS);
}
 /*
* =====================================================================================
*
* Filename: free_and_sbrk.c
*
* Description:
*
* Version: 1.0
* Created: 2014年03月19日 11时37分09秒
* Revision: none
* Compiler: gcc
*
* Author: alan (), alan19920626@gmail.com
* Organization:
*
* =====================================================================================
*/ #include "tlpi_hdr.h" #define MAX_ALLOCS 1000000 int main(int argc, char *argv[]){
char *ptr[MAX_ALLOCS];
int freeStep, freeMin, freeMax, blockSize, numAllocs, j; printf("\n"); if(argc < || strcmp(argv[], "--help") == )
usageErr("%s num-allocs blocksize [step [min [max]]]\n", argv[]); numAllocs = getInt(argv[], GN_GT_0, "num-allocs"); if(numAllocs > MAX_ALLOCS)
cmdLineErr("num-allocs > %d\n", MAX_ALLOCS); blockSize = getInt(argv[], GN_GT_0 | GN_ANY_BASE, "blocksize"); freeStep = (argc > ) ? getInt(argv[], GN_GT_0, "step") : ;
freeMin = (argc > ) ? getInt(argv[], GN_GT_0, "min") : ;
freeMax = (argc > ) ? getInt(argv[], GN_GT_0, "max") : numAllocs; if(freeMax > numAllocs)
cmdLineErr("free-max > num-allocs\n"); printf("Initial program break: %10p\n", sbrk()); printf("Allocing %d*%d bytes\n", numAllocs, blockSize); for(j = ; j < numAllocs; j++){
ptr[j] = malloc(blockSize);
if(ptr[j] == NULL)
errExit("malloc");
printf("After malloc(), program break is: %10p\n", sbrk());
} printf("Program break is now: %10p\n", sbrk()); printf("Freeing blocks from %d to %d in steps of %d\n", freeMin, freeMax, freeStep);
for(j = freeMin-; j < freeMax; j += freeStep)
free(ptr[j]); printf("After free(), program break is %10p\n", sbrk()); exit(EXIT_SUCCESS);
}

测试结果:

lancelot@debian:~/Code/tlpi$ ./-   

Initial program break:           0x1913000
Allocing * bytes
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
After malloc(), program break is: 0x1934000
Program break is now: 0x1934000
Freeing blocks from to in steps of
After free(), program break is 0x1934000

可以清楚的看得出来,内存块只是调用了一次sbrk()来改变program break的位置,分配15块10个字节的内存块,只是第一次的时候调用了sbrk分配了1000个字节的内存块,并将990个字节大小的内存块放到空闲内存块列表,供以后malloc的调用使用。。。。

《Linux/Unix系统编程手册》读书笔记4的更多相关文章

  1. 【鸟哥的Linux私房菜】笔记1

    Linux是什么 从操作系统与cpu架构关系到linux  Richard Mathew Stallman GPL 关于GNU计划 Linux的发展 Linux的核心版本 Linux的特色 Linux ...

  2. 【鸟哥的Linux私房菜】笔记3

    正确地开机 最好不要使用root账号登陆!GNOME图形界面 View items as a list X WindowShell 文本交互界面bash是Shell的名称,Linux的默认壳程序就是b ...

  3. 【鸟哥的Linux私房菜】笔记2

    Linux的应用 学习资源整理 安装记录 >< 1.Linux的应用: 网络服务器 数据库 学术机构的高效运算任务 嵌入式系统 ... 2.挂载与磁盘分区 学习资源整理 学习 1.书上的网 ...

  4. 《鸟哥的Linux私房菜》笔记——02. 关于Linux

    Unix 历史 1969年以前:伟大的梦想--Bell, MIT 与 GE 的「Multics」系统 1969年:Ken Thompson 的小型 file server system 1973年:U ...

  5. 《鸟哥的Linux私房菜》笔记——03. 磁盘分区

    Everything is a file. 常见硬件对应于 Linux 下的文件(/dev目录下) 装置 装置在Linux内的档名 SCSI/SATA/U盘硬盘机 /dev/sd[a-p] U盘 /d ...

  6. 鸟哥的linux私房菜学习笔记 __ 命令与文件的搜寻

    连续输入两次[tab]按键就能够知道使用者有多少命令可以下达.那你知不知道这些命令的完整档名放在哪里?举例来说,ls 这个常用的命令放在哪里呢? 就透过 which 或 type 来找寻吧! 范例一: ...

  7. 【鸟哥的Linux私房菜】笔记

    操作系统核心的功能! 驱动程序与操作系统的关系 2. [计算机组成之组件] 3.CPU实际要处理的数据完全来自于主存储器,这是一个很重要的概念! 4.CPU是整个计算机系统最重要的部分,那么目前世界上 ...

  8. 《鸟哥的Linux私房菜》笔记——04. 简单命令行

    键入命令 [dmtsai@study ~]$ command [-options] parameter1 parameter2 ... 指令 選項 參數(1) 參數(2) 注意:有时也可以使用 + 放 ...

  9. 鸟哥的Linux私房菜学习笔记——文件权限与目录配置

    Linux的文件权限和目录配置 在linux中的每个用户必需属于一个组,不能独立于组外.在linux中每个文件有所有者.所在组.其它组的概念. (1)所有者 一般为文件的创建者,谁创建了该文件,就是天 ...

  10. 鸟哥的Linux私房菜学习笔记(1)

    2014/10/29 1.档案的权限管理分为三个部分: 拥有者.群组.其他 2.ls -al 命令可以看到档案的详细信息 3.档案的属性中由十个部分构成 第一个部分是档案类型 -代表档案.d代表文件夹 ...

随机推荐

  1. Beta版软件说明书

    软件使用说明书 一.    软件概述 本软件面向广大简易图片使用者,旨在为用户提供简单方便的不对其他软件产生依赖的截图软件,可以脱机使用. 二.    运行环境 个人电脑,Windows7操作系统,. ...

  2. web前端网页特效大全导航列表

    CSS3和Html5 图表与图形 表单验证 导航菜单 table选项卡 视频播放器 日期和时间 返回顶部 图层代码 滚动代码 幻灯片 文字特效 图片放大镜 juqery焦点图 瀑布流 广告悬浮代码 在 ...

  3. ZOJ 1111 Poker Hands

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1111 A poker hand consists of 5 ca ...

  4. BZOJ 2820 YY的GCD

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2820 有种方法是枚举质数然后用BZOJ2301来做但是超时了... 具体式子大概张这样: ...

  5. BZOJ1500 维修数列

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1500 [前言] 据说没打这题就相当于没打过Splay,这题简直就是让你内心崩溃的... 这 ...

  6. R 实例1

    //转载:http://www.r-china.net/forum.php?mod=viewthread&tid=881&extra=page%3D1//用R抓取人民日报网数据 lib ...

  7. Hadoop 系统配置 map 100% reduce 0%

    之前在本地配置了hadoop伪分布模式,hdfs用起来没问题,mapreduce的单机模式也没问题. 今天写了个程序,想在伪分布式上跑一下mapreduce,结果出现 map 100% reduce ...

  8. 如何用 Parse 和 Swift 搭建一个像 Instagram 那样的应用?(3)

    [编者按]本篇文章作者是 Reinder de Vries,既是一名企业家,也是优秀的程序员,发表多篇应用程序的博客.本篇文章中,作者主要介绍了如何基于 Parse 特点,打造一款类似 Instagr ...

  9. Appium下Android keyevent整理

    keycode 3:首页(Home key) keycode 4:返回键(Back key) keycode 5:电话键(Call key) keycode 6:结束通话键(End Call key) ...

  10. uva 11374

    Problem D: Airport Express In a small city called Iokh, a train service, Airport-Express, takes resi ...