c语言实现sbrk函数,菜鸟随笔(2)---brk()与sbrk()函数的学习与使用
一只菜鸟横空出世,码农世界闯一闯,每天进展多一丢丢。
brk()与sbrk()函数的学习与使用
brk()与sbrk()函数定义如下:
#include
int brk(boid *addr);
addr:把内存末尾指针设置为addr.返回值:0表示成功,非0表示失败
void *sbrk(intptr_t increment);
increment:把内存的末尾指针移动increment个字节。返回值:上次调用sbrk/brk的内存末尾指针。
内容摘选转自:https://blog.csdn.net/tiankaiying/article/details/8499496
虚拟内存的分配.
栈:编译器自动生成代码维护
堆:地址是否映射,映射的空间是否被管理.
棧和堆这两个数据结构是系统管理的。
这个时候就要使用brk/sbrk函数了。这两个函数都是我们自己申请一块内存,这块内存不再由系统托管。完完全全是我们自己管理。也就是说我们自己要负责这一块内存的使用和释放,系统不再负责了。
1.brk/sbrk 内存映射函数 unix的函数
问题1 怎么知道空闲空间?
问题2 内核的内存分配方式?
每个进程可访问的虚拟内存空间为3G,但在程序编译时,不可能也没必要为程序分配这么大的空间,只分配并不大的数据段空间,程序中动态分配的空间就是从这 一块分配的。如果这块空间不够,malloc函数族(realloc,calloc等)就调用sbrk函数将数据段的下界移动,sbrk函数在内核的管理 下将虚拟地址空间映射到内存,供malloc函数使用。所以sbrk要分配新空间给进程。
内核数据结构mm_struct中的成员变量start_code和end_code是进程代码段的起始和终止地址,
start_data和 end_data是进程数据段的起始和终止地址,
start_stack是进程栈段起始地址,
start_brk是进程动态内存分配起始地址(堆的起始地址),
还有一个 brk(堆的当前的终止地址),就是动态内存分配当前的终止地址。
C语言的动态内存分配基本函数是malloc(),在Linux上的基本实现是通过内核的brk系统调用。brk()是一个非常简单的系统调用,
brk只是简单地改变mm_struct结构的成员变量brk的值。
分配释放内存:
int brk(void *end);//分配空间,释放空间 实际是改变end_ptr的值
移动访问的范围
end_ptr > sbrk(0) //分配
end_ptr < sbrk(0) //释放
void *sbrk(int size);//只做空间分配,返回分配空间的首地址
size = 0 得到大块空闲空间的首地址指针. 但这个指针没有映射还不能用
> 0 分配指定空间,end_ptr移动到末尾,每次分配从end_ptr开始,返回这片空间的首地址指针,并且把end_ptr指针位置+size
< 0 释放空间 返回释放的空间的end_ptr的地址(这个地址已经不能用了),并将空间指针回移。
应用:
1.使用sbrk分配空间
2.使用sbrk得到没有映射的空间的虚拟地址.
int *p = sbrk(0); //p这个指针还不能用,还没映射。
*p = 40;//给没有映射的空间赋值,段错误。
如果参数不是0,就帮你映射size的空间,以页为单位的分配。
3.使用brk分配空间
int* p = sbrk(0); // int* p = sbrk(9);这里的效果一样,因为后面brk又把末尾指针往前移动了。
brk(p+1); //这里虽然只是加1个字节,但是映射了一个页4k。
int* q = sbrk(0);
//这时候返回的地址与p相差4个字节,按brk移动的字节数末尾,开始向高地址(未分配区)分配。brk指向的地方是标记为已经用的。
*p=40;
*(p+40)=60;//证明映射的不只1个字节,不会有段错误,但逻辑上不这么用
brk + 链表结构管理 = malloc
malloc+初始化 = new
4.使用brk释放空间
理解:
sbrk(int size)
sbrk与brk后台系统维护一个指针.
指针默认是null.
调用sbrk,判定指针是否是0,是:得到大块空闲空间的首地址初始化指针.
同时把指针+size
否:返回指针,并且把指针位置+size
应用案例:
写一个程序查找1-10000之间所有的素数.
并且存放到缓冲,然后打印.
缓冲的实现使用sbrk/brk
流程:
循环
判定是否素数(isPrimer)
是,分配空间存放
不是,继续下步.
#include
#include
int isPrimer(int a)
{
int i;
for(i=2;i
{
if(a%i==0)
{
return 1;
}
}
return 0;
}
main()
{
int i=2;
int b;
int *r;
int *p;
p=sbrk(0);
r=p;
for(;i<100;i++)
{
b=isPrimer(i);
if(b==0)
{
brk(r+1); //末尾指针end_ptr=(r+1); 所以r被映射了。
*r=i;
r=sbrk(0);
}
}
i=0; r=p;
while(r!=sbrk(0))
{
printf("%d\n",*r);
r++;
}
brk(p);//free
}
原文:https://www.cnblogs.com/1996-1-0-3-0/p/9267826.html
c语言实现sbrk函数,菜鸟随笔(2)---brk()与sbrk()函数的学习与使用相关推荐
- c语言 函数指针 菜鸟教程,C 函数指针与回调函数 | 菜鸟教程
函数指针 函数指针是指向函数的指针变量. 通常我们说的指针变量是指向一个整型.字符型或数组等变量,而函数指针是指向函数. 函数指针可以像一般函数一样,用于调用函数.传递参数. 函数指针变量的声明: t ...
- brk函数 linux,brk和sbrk及内存分配函数相关-linux+内存
brk和sbrk主要的工作是实现虚拟内存到内存的映射.在GNUC中,内存分配是这样的: 每个进程可访问的虚拟内存空间为3G,但在程序编译时,不可能也没必要为程序分配这么大的空间,只分配并不大的数据段空 ...
- R语言ggplot2可视化:ggplot2可视化散点图并使用geom_mark_circle函数在数据簇或数据分组的数据点周围添加圆圈进行注释(自定义圆圈的大小)
R语言ggplot2可视化:ggplot2可视化散点图并使用geom_mark_circle函数在数据簇或数据分组的数据点周围添加圆圈进行注释(自定义圆圈的大小) 目录
- R语言data.table导入数据实战:data.table中编写函数并使用SD数据对象
R语言data.table导入数据实战:data.table中编写函数并使用SD数据对象 目录 R语言data.table导入数据实战:data.table中编写函数并使用SD数据对象 #data.t ...
- R语言使用rpart包构建决策树模型、使用prune函数进行树的剪枝、交叉验证预防过拟合、plotcp可视化复杂度、rpart.plot包可视化决策树、使用table函数计算混淆矩阵评估分类模型性能
R语言使用rpart包构建决策树模型.使用prune函数进行树的剪枝.使用10折交叉验证选择预测误差最低的树来预防过拟合.plotcp可视化决策树复杂度.rpart.plot包可视化最终决策树.使用t ...
- R语言ggplot2可视化:使用ggfortyify包中的autoplot函数自动可视化时间序列数据(Time Series Plot From a Time Series Object (ts))
R语言ggplot2可视化:使用ggfortyify包中的autoplot函数自动可视化时间序列数据(Time Series Plot From a Time Series Object (ts)) ...
- R语言data.table导入数据实战:data.table使用by函数进行数据分组(aggregate)
R语言data.table导入数据实战:data.table使用by函数进行数据分组(aggregate) 目录 R语言data.table导入数据实战:data.table使用by函数进行数据分组( ...
- R语言使用R基础安装中的glm函数构建乳腺癌二分类预测逻辑回归模型、分类预测器(分类变量)被自动替换为一组虚拟编码变量、summary函数查看检查模型、使用table函数计算混淆矩阵评估分类模型性能
R语言使用R基础安装中的glm函数构建乳腺癌二分类预测逻辑回归模型(Logistic regression).分类预测器(分类变量)被自动替换为一组虚拟编码变量.summary函数查看检查模型.使用t ...
- R语言使用coin包应用于分类变量独立性问题的置换检验(permutation tests)、使用普通卡方检验chisq.test函数和置换近似卡方检验chisq.test函数、检验分类变量的独立性
R语言使用coin包应用于分类变量独立性问题的置换检验(permutation tests).使用普通卡方检验chisq.test函数和置换近似卡方检验chisq.test函数.检验分类变量的独立性( ...
- R语言编写自定义描述统计计算函数、使用doBy包的summaryBy函数计算不同分组(group)的描述性统计值(Descriptive statistics by group、样本个数、均值、标准)
R语言编写自定义描述统计计算函数.使用doBy包的summaryBy函数计算不同分组(group)的描述性统计值(Descriptive statistics by group using summa ...
最新文章
- CentOS7 升级 Git 版本
- 安卓动态.9图拉伸实现方案
- CTSC2017APIO2017
- 拓端tecdat|R语言arima,向量自回归(VAR),周期自回归(PAR)模型分析温度时间序列
- tftpd32+ tftpd64文件传输安装和使用教程【图文并茂】
- 开发了一个拼多多淘宝闲鱼所有虚拟店商品通过百度网盘自动发货机器人软件助手
- 【托业】【新托业TOEIC新题型真题】学习笔记13-题库四-P7
- 第4章 数据库应用系统功能设计与实施
- 【Java数据结构与算法】Java如何实现环形队列
- Ubuntu硬盘分区/格式化/挂载文件系统各种应用(转载)
- 最新最全的免费股票数据接口--沪深A股深度分析机构持股数据API接口(十二)
- SAP 今年上半年的业绩非常
- 剪刀石头布java_java编写剪刀石头布游戏
- ACA-MB600面包机成功配方(献给最菜的菜鸟们)
- 重磅 | 清华刘洋与邓力合著338页新书《Deep Learning in NLP》(附下载)
- Everything-Everything下载
- 2345王牌输入法及使用教程
- OPPO手机无法读取通知类短信
- 干货 :麦肯锡教我的数据科学家的五大黄金法则
- 电脑没有ps怎么改照片dpi?怎么改照片dpi为300?