在堆上分配内存:malloc和free

一般情况下,C程序使用malloc函数族在堆上分配和释放内存。较之brk和sbrk,这些函数具备不少优点:

属于C语言标准的一部分

更易于在多线程程序中使用

接口简单,允许分配小块内存

允许随意释放内存块,它们被维护于一张空闲内存列表中,在后续内存分配调用时循环使用

malloc函数在堆上分配参数size字节大小的内存,并返回指向新分配内存起始位置处的指针,其所分配的内存未经初始化。

#include <stdlib.h>
void *malloc(size_t size); /* Returns pointer to allocated memory on sucess, or NULL on error */

由于malloc的返回类型为void*,因而可以将其付赋给任意类型的C指针。malloc返回内存块所采用的的字节对齐方式,总是适宜于高效访问任何类型的C语言数据结构。在大多数硬件架构上,这意味着malloc是基于8字节或16字节边界来分配内存的。

SUSv3规定:调用malloc(0)要么返回NULL,要么是一小块可以(并且应该)用free释放的内存。Linux的malloc(0)遵循的是后者。

如果无法再分配内存(或许是因为已经达到了program break所能达到的地址上限),则malloc返回NULL,并设置errno以返回错误信息。

虽然分配内存失败的可能性很小,但所有对malloc以及后续提及的相关函数的调用都应对返回值进行错误检查。

free函数释放ptr参数所指向的内存块,该参数应该是之前由malloc,或者后续描述的其他堆内存分配函数之一所返回的地址。

#include <stdlib.h>
void free(void *ptr);

一般情况下,free并不降低program break的位置,而是将这块内存填加到空闲内存列表中,供后续的malloc函数循环使用。这么做是出于以下几个原因。

被释放的内存块通常会位于堆的中间,而非堆的顶部,因而降低program break是不可能的。

它最大限度地减少了程序必须执行的sbrk调用次数。

在大多数情况下,降低program break的位置不会对那些分配大量内存的程序有多少帮助,因为它们通常倾向于持有已经分配内存或是反复释放和重新分配内存,而非释放所有内存后再持续运行一段时间。

如果传给free的是一个空指针,那么函数将什么都不做。(换句话说,给free传入一个空指针并不是错误代码。)

在调用free后对参数ptr的任何使用,例如将其再次传递给free,将产生错误,并可能导致不可预知的结果。

Unix系统编程()在堆上分配内存的更多相关文章

  1. Java中对象并不是都在堆上分配内存的

    转(https://blog.51cto.com/13906751/2153924) 前段时间,给星球的球友们专门码了一篇文章<深入分析Java的编译原理>,其中深入的介绍了Java中的j ...

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

    2018-1-30 一.UNIX.C语言以及Linux的历史回顾 1. UNIX简史.C语言的诞生 1969年,贝尔实验室的Ken Thompson首次实现了UNIX系统. 1973年,C语言步入成熟 ...

  3. Unix系统编程()brk,sbrk

    在堆上分配内存 进程可以通过增加堆的大小来分配内存,所谓堆是一段长度可变的连续虚拟内存,始于进程的未初始化数据段末尾,随着内存的分配和释放而增减.通常将堆的当前内存边界称为"program ...

  4. Java中的对象都是在堆上分配的吗?

    作者:LittleMagic https://www.jianshu.com/p/8377e09971b8 为了防止歧义,可以换个说法: Java对象实例和数组元素都是在堆上分配内存的吗? 答:不一定 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 关于loader加载的东西必须是继承sprite

    如果不是继承sprite

  2. C#应用视频教程2.2 OPENGL虚拟仿真介绍

    三维在理解了如何绘制2D元素之后,我们尝试绘制3D元素. 其实多个三角形也能够成四面体,多个长方形也能够成六面体,所以绘制3D元素的时候,只要顶点数量匹配就行了   这里我们尤其注意,我把绘制之前的三 ...

  3. 开源工作流CCBPM中关于解决谷歌等浏览器silverlight的问题

    CCBPM的流程设计器和表单设计器.是通过silverlight实现的. 有些用户和学习者在安装完CCFlow,执行流程设计器时,常常会出现提示安装silverlight.明明已经安装了,为什么还会出 ...

  4. ! Undefined control sequence. \CJK@XXX ...endcsname {`#2}{`#3}\CJK@ignorespaces \fi l.43 \end{document}

    错误的原因是:你的文本内容超过了一页,需要增加新的一页. 解决问题的方法就是在\end{CJK}或者\end{CJK*}之前加入\newpage,\clearpage或者\cleardoublepag ...

  5. 右键菜单 GenericMenu

    http://www.cnblogs.com/zhaoqingqing/p/3799294.html 自定义窗口中使用右键菜单: // This example shows how to create ...

  6. ssh登陆不上

    用ssh key登陆不上某台机A的某个账号xy1,查看A的/var/log/messages,看到有这么句: User xy1 not allowed because account is locke ...

  7. openerp在ubuntu中查看日志

    sudo su - openerp -s /bin/bash less /var/log/openerp/openerp-server.log

  8. iOS开发- 隐藏键盘总结

    一.隐藏自身软键盘 当对于有多个UITextField控件都想通过点击"Return"来隐藏自身软键盘的情况.这时的最好办法是使用Did End on Exit事件.在点击软键盘右 ...

  9. 安装 percona-xtrabackup 2.4

    Installing Percona XtraBackup from Percona yum repository Install the Percona repository You can ins ...

  10. Python-多线程学习总结

    我们在做软件开发的时候很多要用到多线程技术.例如如果做一个下载软件象flashget就要用到.象在线视频工具realplayer也要用到因为要同时下载media stream还要播放.其实例子是很多的 ...