首页 > 系统相关 >C内存分配

C内存分配

时间:2023-04-29 09:33:45浏览次数:47  
标签:malloc free break program 内存 分配

堆上内存分配

1.brk()和sbrk()

progam break

program break记录了堆顶的地址,当使用brk或者sbrk系统调用时,program break的位置会随之改变
image

brk()

#include <unistd.h>
int brk(void *end_data_segment);

brk(void *end_data_segment)将program break 抬升到end_data_segment处,成功返回0,失败返回-1。


sbrk()

#include <unistd.h>
void *sbrk(intptr_t increment);

sbrk()将原本的program break再增加increment大小,成功返回前一个program break的地址,失败返回(void *)-1。此外,调用sbrk(0)将会返回当前program break的地址。


2.malloc和free

malloc()

#include <stdlib.h>
void *malloc(sizet_t size);

在堆上分配size字节大小的空间,成功则返回分配空间的起始地址,失败则返回NULL。
malloc分配内存失败的原因有可能是已经抵达系统所限制的program break上限

free()

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

free()将malloc分配的空间回收,参数ptr为调用malloc返回的空间起始地址,这里可能会有一个疑问,我们只传递了一个地址给free,free如何知道要回收的空间大小呢。

image

实际上,malloc分配的内存块头部会记录这块内存块的大小。一般情况下,free并不会降低program break的位置,而是将free掉的内存块记录在空闲内存表中方便malloc再次使用,这么做的原因是:

  1. free释放掉的内存块并不总是在堆顶,program break并不会随着free而降低
  2. 减少sbrk()的次数,降低系统开销
  3. 对于大量持有内存程序经常反复malloc和free,降低program break的位置对程序来说并没有帮助

所以仅当堆顶有足够大量空闲区域时,free的glibc实现会将program break的位置降低,对"足够"的定义区别于molloc函数包中定义的参数(典型值为128KB)。
image

当使用malloc时,会优先从空闲内存列表中查找满足大小的空闲块,如果内存块刚好等于用户要求分配的大小,就把这块内存从空闲内存表中移除,并把地址返回给用户,如果大于用户要求分配的空间则会从空闲块中切割一部分出来分给用户。

在使用malloc和free时应遵守:

  1. 非经malloc函数包(包括malloc , calloc , realloc )分配的内存空间,禁止使用free释放。
  2. 在一个需要持续长时间运行的程序中,对于malloc分配的空间要及时释放。否则,堆将稳步增长直至达到虚拟内存空间的上限,再申请内存都将会失败,这个称为"内存泄漏"。

3.calloc和realloc

calloc

include <stdlib.h>
void *calloc(sizet_t num , sizet_t size);

分配一个num*size字节大小的内存空间,成功返回分配的内存块起始地址,失败返回NULL
他的通常用法是:

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

realloc

#include <stdlib.h>
void *realloc(void *ptr,sizet_t size);

realloc将malloc或者calloc分配的内存空间调整至size大小,并将原来的数据复制到当前地址块,成功返回分配的内存块起始地址,失败返回NULL。

提示:realloc返回的地址可能与传入的地址不同,当返回了不同的地址后,之前的地址不可再用

当调用realloc来增大空间时,realloc会试图合并ptr之后相邻的空闲块然后分配给用户,如果空闲块空间不足以满足要求时,realloc将会放弃ptr指向的内存块,寻找新的空闲块,并将原来的数据复制到找到的空闲内存块,然后返回新的地址。
image

2.栈上内存分配alloca

#include <alloca.h>
void *alloca(sizet_t size);

与malloc函数包不同alloca会在栈上分配空间,也不需要free来释放,不能通过realloc来修改大小,因为在函数中使用alloca分配的空间会随着函数结束而自动释放。
alloca分配速度要快于malloc,成功返回分配的内存起始地址,失败则返回NULL。

标签:malloc,free,break,program,内存,分配
From: https://www.cnblogs.com/ljq245055804/p/17363547.html

相关文章

  • 12 Linux的伙伴系统和SLAB分配器
    伙伴系统: buddy物理内存页面管理算法,最先源自Sun公司的Solaris操作系统;Linux后来也引入了伙伴系统;表示一个物理内存页面:Linux定义了一个page结构体,大量使用了c的union联合体定义结构字段,其大小取决于结构体里面占用内存最大的变量决定;好处是信息量很多,占用内存很少;一个page......
  • 使用Addressable更好的管理内存
    你好,我是郑洪智,你可以叫我大智。我正在带小新学Unity。洪流学堂公众号回复addr,可以下载Addressable中文手册,更有视频教程哦~小新:“智哥,Assetbundle我只是大概学了一下,但是没咋用过。你说不用它就会有内存问题?”大智:“咱们来一起做个测试吧。对于工程里的资源,一般有三种方式加载实例......
  • 【GPU基础问题】GPU内存占用率很高利用率很低
    前言 问题描述查看nvidia-smi,发现显存占比很高,但是GPU-Util(GPU利用率)很低,在3%、7%、11%等几个参数之间反复跳动。watch-n0.5nvidia-smi也就是显卡并没有完全利用起来,导致训练很慢。原因分析GPU内存占用率(memoryusage) GPU内存利用率(volatileGPU-Util)  ......
  • java方法的内存及练习
    方法的内存一、方法调用的基本内存原理:Java内存分配栈:方法运行时使用的内存方法进栈运行,运行完毕就出栈堆:newl出来的,都在堆内存中开辟了一个小空间方法区:存储可以运行的class文件本地方法栈:JVM在使用操作系统功能的时候使用和我们开发无关寄存器:给CPU使用和......
  • 10 如何表示虚拟内存
    x86CPU的虚拟地址空间划分:一个应用往往拥有很大的连续地址空间,并且每个应用都是一样的,只有在运行时才能分配到真正的物理内存,在操作系统中被称为虚拟内存;x86CPU支持虚拟地址时要么开启保护模式要么开启长模式;保护模式下是32位,没有进行任何划分;长模式下64位,但是CPU只是实现了4......
  • Linux 内存管理 pt.1
    哈喽大家好,我是咸鱼 今天我们来学习一下Linux操作系统核心之一:内存 跟CPU一样,内存也是操作系统最核心的功能之一,内存主要用来存储系统和程序的指令、数据、缓存等 关于内存的学习,我会尽量以通俗易懂的方式且分成多篇文章去讲解 那么今天在pt.1文章中,我们来学习......
  • Jenkins java程序占用内存大 优化
       Linux系统下使用top命令,再输入M按钮,按照内存排序每个进程,发现jenkins占据内存过大,如下:   解决方式输入命令vim/etc/sysconfig/jenkins编辑jenkins文件,修改JENKINS_JAVA_OPTIONS属性:原来的属性如下: JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"  ......
  • 内存分页
    publicstatic<T>PageResult<T>newPage(List<T>content,IntegerpageNum,Integerpages){inttotal=content.size();intoffset=(pageNum-1)*pages;if(offset>total){returnnewPageResult<T>(null,pag......
  • SpringBoot SpringSecurity 介绍(基于内存的验证)
    SpringBoot集成SpringSecurity+MySQL+JWT附源码,废话不多直接盘SpringBoot已经为用户采用默认配置,只需要引入pom依赖就能快速启动SpringSecurity。目的:验证请求用户的身份,提供安全访问优势:基于Spring,配置方便,减少大量代码内置访问控制方法permitAll()表示所匹配的......
  • 音视频八股文(6)-- ffmpeg大体介绍和内存模型
    播放器框架常用音视频术语•容器/文件(Conainer/File):即特定格式的多媒体文件,比如mp4、flv、mkv等。•媒体流(Stream):表示时间轴上的一段连续数据,如一段声音数据、一段视频数据或一段字幕数据,可以是压缩的,也可以是非压缩的,压缩的数据需要关联特定的编解码器(有些码流音频他是纯PCM)......