linux虚拟内存的分配

#include <stdio.h>
#include <unistd.h>
int isPrimer(int a)
{	
	int i;
	for(i=2;i<a;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);//分配一个内存地址
			*r=i;
			r=sbrk(0);//返回上一个分配地址结束的地方的地址
		}
	}
	
	i=0;
	r=p;
	while(r!=sbrk(0))
	{
		printf("%d\n",*r);
		r++;
	}
	brk(p);//free
	
}


内存管理

硬件层次
内存结构管理
内核层次
内存映射
堆扩展
语言层次
c:malloc  
c++:new
数据结构
STL
智能指针
1.问题:
malloc怎么分配空间?
malloc与new的关系?

2.Linux对内存的结构描述
1./proc/${pid}/  存放进程运行时候所有的信息(包括内存结构)

结论:
任何程序的内存空间分成4个基本部分
1.代码区
2.全局栈区
3.堆
4.局部栈
进程查看
ps aue

2.理解程序的变量与内存空间的关系

结论:
1.内存分四个区.
2.各种变量对应存放区
3.堆栈是一种管理内存的数据结构.
4.查看程序的内存地址.
3.理解malloc的工作的原理
malloc使用一个数据结构(链表)维护分配空间
链表的构成:分配的空间/上一个空间数据/下一个空间/空间大小等信息.
对malloc分配的空间不要越界访问.因为容易破坏后台维护结构.导致malloc/free/calloc/realloc不正常工作.

4.C++的new与malloc的关系
malloc    new new[] 
realloc new()
calloc    new[]
free delete  delete[]?

结论:new的实现使用的是malloc来实现的.
区别:new使用malloc后,还要初始化空间.
基本类型,直接初始化成默认值.
UDT类型,调用指定的构造器
delete调用free实现.
delete负责调用析构器.然后在调用free
new与new[]区别
new只调用一个构造器初始化.
new[]循环对每个区域调用构造器.
delete 与delete[]

5.函数调用栈空间的分配与释放
5.1.总结:
1.函数执行的时候有自己的临时栈.
2.函数的参数就在临时栈中.如果函数传递实参.则用来初始化临时参数变量.

3.通过积存器返回值.(使用返回值返回数据)
4.通过参数返回值.(参数必须是指针)
指针指向的区域必须事先分配.
5.如果参数返回指针.参数就是双指针.

5.2.__stdcall __cdecl __fastcall
1.决定函数栈压栈的参数顺序.
2.决定函数栈的清空方式
3.决定了函数的名字转换方式.

6.far near huge指针
near 16
far  32
huge 综合

四.虚拟内存
问题:
一个程序不能访问另外一个程序的地址指向的空间.
理解:
1.每个程序的开始地址0x80084000
2.程序中使用的地址不是物理,而是逻辑地址(虚拟内存).
逻辑地址仅仅是编号.编号使用int 4字节整数表示.
4294967296
每个程序提供了4G的访问能力
问题:
逻辑地址与物理地址关联才有意义:过程称为内存映射.
背景:
虚拟内存的提出:禁止用户直接访问物理存储设备.
有助于系统的稳定.

结论:
虚拟地址与物理地址映射的时候有一个基本单位:
4k  1000 内存页.
段错误:无效访问.
合法访问:比如malloc分配的空间之外的空间可以访问,但访问非法.

虚拟内存的分配.
栈:编译器自动生成代码维护
堆:地址是否映射,映射的空间是否被管理.
1.brk/sbrk 内存映射函数


补充:帮助手册
man 节  关键字
1-8  1:Linux系统(shell)指令
 
2:系统函数
3:标准C函数
 
7:系统编程帮助

分配释放内存:
int brk(void *end);//分配空间,释放空间
void *sbrk(int size);//返回空间地址
应用:
1.使用sbrk分配空间
2.使用sbrk得到没有映射的虚拟地址.
3.使用brk分配空间
4.使用brk释放空间

理解:
sbrk(int  size)
sbrk与brk后台系统维护一个指针.
指针默认是null.
调用sbrk,判定指针是否是0,是:得到大块空闲空间的首地址初始化指针.
同时把指针+size
否:返回指针,并且把指针位置+size


总结:
智能指针
 stl
new
malloc
brk/sbrk
异常处理
int brk(void*)
void *sbrk(int);
如果成功.brk返回0   sbrk返回指针
失败 brk返回-1  sbrk返回(void*)-1

Unix函数错误,修改内部变量:
errno

字符串函数string.h  cstring
内存管理函数malloc memset mamcmp memcpy ...
bzero
错误处理函数
标准IO函数
时间函数

类型转换函数

回顾:
brk/sbrk
int brk(void *p);
void *sbrk(int);

维护一个位置。brk/sbrk改变这个位置
brk改变绝对位置。
sbrk相对改变位置。

补充:全新的类型。
永远记住:c的基本类型就:整数(1,2,4),小数(4,8)
unsigned signed
所有全新类型都是使用typedef重新定义。
新的类型的C的原型。
类型重定义的好处:
1.维护方便
2.移植
3.容易理解


映射虚拟内存
没有任何额外维护数据的内存分配。
mmap(分配)/unmap(释放)
1.函数说明
void *mmap(
void *start,//指定映射的虚拟地址 0由系统指定开始位置)
size_t length,//映射空间大小 pagesize倍数
int prot,//映射权限  PROT_NONE | PROT_READ PROT_WRITE PROT_EXEC
int flags,//映射方式
int fd,//文件描述符号
offset_t off);//文件中的映射开始位置(必须是pagesize的倍数)

映射方式:
内存映射:匿名映射。
文件映射:映射到某个文件
 只有文件映射最后两个参数有效。

MAP_ANONYMOUS 
MAP_SHARED   MAP_PRIVATE(二选一)

#include <unistd.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
main()
{
	int *p=mmap(
		NULL,
		getpagesize(),
		PROT_READ,
		MAP_ANONYMOUS|MAP_SHARED,
		0,0);
	*p=20;
	*(p+1)=30;
	*(p+2)=40;
	
	printf("%d\n",p[2]);
	munmap(p,4096);
}



2.案例
3.总结
选择什么样的内存管理方法?
智能指针(指针池)
STL
new
malloc (小而多数据) 
brk/sbrk (同类型的大块数据,动态移动指针)
mmap/munmap(控制内存访问/使用文件映射/控制内存共享)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值