在堆上分配内存: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. Cocos2d-x 2.x 升级为 3.x 常见变化纪录

    1.去CC 之前2.0的CC**,把CC都去掉,主要的元素都是保留的 2.0 CCSprite  CCCallFunc CCNode .. 3.0 Sprite CallFunc Node .. 2. ...

  2. OpenVPN多处理之-为什么不

    OpenVPN没有多处理.人所皆知.我觉得我有点啰嗦了.天天说这个事.为什么没有多处理呢?我们来看下OpenVPN的作者,大牛级别的,早已超越代码的重量级人物,James Yonan(简称JY)是怎么 ...

  3. java 和 C# 响应输出的相似度

    java servlet response: bf.append("Shipment No, STT No, WIN Event, DateTime, WOU Envent, DateTim ...

  4. Sublime key

    -– BEGIN LICENSE -– TwitterInc 200 User License EA7E-890007 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA ...

  5. OE context 传参数

    来自:http://shine-it.net/index.php/topic,16360.0.html 有个需求想many2one字段关联显示的value在各个模块显示不同的值. 如果直接该rel_n ...

  6. form表单元素设置只读

      form表单元素设置只读 CreateTime--2017年5月5日11:42:41 Author:Marydon 1.设置文本框只读 <!-- 方法一:简写 --> <inpu ...

  7. js与jQuery方法对比

      javascript与jQuery方法对比jquery对象转dom对象 // 方式一(推荐使用) $("input")[0] // 方式二 $("input" ...

  8. java线程-java多线程之可见性

    可见性:一个线程对共享变量值的修改,能够及时呗其他线程看到. 共享变量:如果一个变量在多个线程的内存中都存在副本,那么这个变量就是这几个线程的共享变量. java内存模型(JMM) 描述了java程序 ...

  9. Android Studio集成SVN报错:can&#39;t use subversion command line client : svn

    Android Studio集成SVN插件,check out出代码后.每次开启都会在右上角出现例如以下错误: Can't use Subversion command line client: sv ...

  10. 【微信开发】JS和PHP分别判断当前浏览器是否微信浏览器

    1.PHP端 //判断是否微信浏览器 -xzz1125 function is_weixin() { if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMes ...