【Linux_Unix系统编程】chapter7 内存分配

Chapter7 内存分配
本章将用于在堆或者栈上分配内存的函数。
7.1 在堆上分配内存
通常将堆的当前的内存边界称为"program break"

7.1.1 调整program break: brk()和sbrk()
改变堆的大小(即分配或者释放内存),其实就像命令内核改变进程的program break位置一样简单。
传统的UNIX系统提供了两个操纵program break的系统调用:brk()和sbrk().
#include <unistd.h>
int brk(void *end_data_segmeng);
void *sbrk(intptr_t increment);

7.1.2 在堆上分配内存:malloc()和free()
一般情况下,C语言使用malloc函数族在对上分配和释放内存。比较brk()和sbrk(),具有以下优点
(1):属于C语言标准部分
(2):更易于在多线程中使用
(3):接口简单,允许分配小块内存
(4):允许随意释放内存块,他们被维护在于一个空闲的内存列表中,在后续内存分配调用是循环使用。

#include <stdlib.h>
void *malloc(size_t size);
malloc()返回内存块所采用字节对齐方式,总是适用于高效访问任何类型的C语言数据结构。在大多数硬件结构上,这意味着malloc是基于8字节或16字节边界来分配内存的。

free()函数释放ptr参数所指向的内存块,该参数应该是之前由malloc().
#include <stdlib.h>
void free(void *ptr);

7.1.3 malloc()和free()的实现

malloc()调试的工具和库

7.1.4 在堆上分配内存的其他方法
用calloc()和realloc()分配内存
#include <stdlib.h>
void *calloc(size_t numitms, size_t size);
numitms:指定分配对象的数量
size:指定每个对象的大小
注意:calloc()会将分配的内存初始化为0,而malloc()返回的是为初始化的内存空间。
eg:
struct { /**/}myStruct;
struct myStruct *p;

p = calloc(1000, sizeof(struct myStruct));
if(p == NULL)
errExit("calloc");

realloc()函数用来调整(通常是增加)一块内存的大小,而此块内存应该是之前由malloc包中函数所分配的。
#include <stdlib.h>
void *realloc(void *ptr, size_t size);
realloc()增加了已分配的内存块的大小,则不会对额外分配的字节进行初始化。
使用calloc() 和realloc()分配的内存应使用free()来释放。

分配对齐的内存:memalign()和posix_memalign()
目的:在分配内存的时候,起始地址要与2的整数次幂边界对齐。
#include <malloc.h>
void *memalign(size_t boundary, size_t size);
作用:分配size个字节的内存,起始地址的参数boundary的整数倍,而boundary必须是2的整数次幂。

posix_memalign(),该函数由标准委员会于近期创建,只是出现在了少数UNIX实现上。
#include <stdlib.h>
int posix_memalign(void **memptr, size_t alignment, size_t size);

7.2 在堆栈上分配内存:alloca()
alloca()也可以动态分配内存,不过不是从堆上分配内存,而是通过增加栈帧的大小从堆栈上分配。
#include <alloca.h>
void *alloca(size_t size);
注意:不需要(实际上也决不能)调用free()来释放由alloca分配的内存。同样也不能调用realloc()来调整由alloca()分配的内存大小。
不能再一个函数的参数列表中调用alloca().

时间: 2024-10-29 11:33:01

【Linux_Unix系统编程】chapter7 内存分配的相关文章

【Linux_Unix系统编程】chapter6 进程

chapter6 进程 重点关注进程虚拟内存的布局及内容.6.1 进程和程序 进程(process)是一个可执行程序(program)的实例. 程序是包含了一系列信息的文件,这些信息描述了如何在运行时创建一个进程,所包含的内容如下. (1):二进制格式标识:每个程序文件都包含用于描述可执行文件格式的元信息. (2):机器语言指令:对程序算法进行编码 (3):程序入口地址:标识程序开始执行时的起始指令位置. (4):数据:包含的变量初始值和程序使用的字面量值 (5):符号表以及重定位表:描述程序中

【Linux_Unix系统编程】Chapter4 文件IO

Chapter4 文件IO 4.1 概述 文件描述符 == Windows的句柄 标准文件描述符: 0 标准输入 STDIN_FILENO stdin 1 标准输出 STDOUT_FILENO stdout 2 标准错误 STDERR_FILENO stderr (1):fd = open(pathname, flags, mode) (2):numread = read(fd, buffer, count) (3):numwritten = write(fd, buffer, count) (

【Linux_Unix系统编程】Chapter10 时间

chapter10 时间 1:真实时间:度量这一时间的起点有二:(1)某个标准点:(2)进程生命周期内的某个固定时点(通常为程序启动) 2:进程时间:一个进程所使用的CPU时间总量,适用于对程序,算法性能的检查或优化.10.1 日历时间(calendar Time) 日历时间存储于类型为time_t的变量中. 系统调用gettimeofday(),可于tv指向的缓冲区中返回日历时间 #include <sys/time.h> int gettimeofday(struct timeval *t

【Linux_Unix系统编程】Chapter8 用户和组

chapter8 用户和组 8.1 密码文件 /etc/passwd 每行都包含7个字段,之间用冒号分割,如下所示: mtk:x:1000:100:Michael:/home/mtk:/bin/base 按顺序介绍着7个字段: 登录名: 经过加密的密码:长度为13个字符 用户ID: 组ID: 注释:该字段存放关于用户的描述性文字. 主目录:用户登录后所处的初始路径 登录shell:一旦用于登录,便交由该程序控制 8.2 shadow密码文件: /etc/shadow 8.3 组文件:/etc/g

【Linux_Unix系统编程】chapter5 深入探究文件IO

Chapter5 深入探究文件I/O 本章节将介绍另一个与文件操作相关的系统调用:多用途的fcntl(),并展示其应用之一读取和设置打开文件的状态标志. 5.1 原子操作和竞争条件 所有系统调用都是以原子操作方式执行的.是以为内核保证了某系统调用中的所有步骤会作为独立操作而一次性加以执行,其间不会为其他进程或线程所中断. 以独占方式创建一个文件: 当同时制定O_EXCL与O_CREAT作为open()标志位时,如果要打开的文件已存在,则open()将返回一个错误.保证了进程是打开文件的创建者.

【Linux_Unix系统编程】Chapter9 进程凭证

chapter9 进程凭证 每个进程都有一套用数字表示的用户ID(UID)和组ID(GID).有时也将这些ID称子为进程凭证. 1:实际用户ID和实际组ID 2:有效用户ID和有效组ID 3:保存的set-user-ID 和保存的set-group-ID 4:文件系统用户ID和文件系统组ID 5:辅助组ID9.1 实际用户ID和实际组ID 实际用户ID和实际组ID确定了进程所属的用户和组.作为登录过程的步骤之一,登录shell从/etc/passed文件中读取相应用户密码记录的第三字段和第四字段

windows内存详解(一) 全面介绍Windows内存管理机制及C++内存分配实例

十分感谢MS社区的帖子,讲得很好~ http://social.technet.microsoft.com/Forums/zh-CN/2219/thread/afc1269f-fe08-4dc7-bb94-c395d607e536 (一):进程空间 在编程中,很多Windows或C++的内存函数不知道有什么区别,更别谈有效使用:根本的原因是,没有清楚的理解操作系统的内存管理机制,本文企图通过简单的总结描述,结合实例来阐明这个机制. 本文目的: 对Windows内存管理机制了解清楚,有效的利用C+

SQLite剖析之动态内存分配

SQLite通过动态内存分配来获取各种对象(例如数据库连接和SQL预处理语句)所需内存.建立数据库文件的内存Cache.以及保存查询结果.我们做了很多努力来让SQLite的动态内存分配子系统可靠.可预测.健壮并且高效.本文概述SQLite的动态内存分配,软件开发人员在使用SQLite时可以据此获得最佳性能. 1.特性    SQLite内核和它的内存分配子系统提供以下特性:    (1)对内存分配失败的健壮处理.如果一个内存分配请求失败(即malloc()或realloc()返回NULL),SQ

垃圾收集机制与内存分配策略

Java 语言与其他编程语言有一个非常突出的特点,自动化内存管理机制.而这种机制离不开高效率的垃圾收集器(Garbage Collection)与合理的内存分配策略,这也是本篇文章将要描述的两个核心点. 引一句周志明老师对 Java 中的内存管理机制的描述: Java 与 C++ 之间有一堵有内存动态分配和垃圾收集技术所围成的「高墙」,墙外面的人想进去,墙里面的人却想出来. 各有各的优势,没有谁会替代谁,只是应用在不同的场合下,谁更适合而已. 可达性分析算法 Java 中使用「可达性分析算法」来