您的位置:首页 > 运维架构 > Linux

Linux虚拟内存-brk/sbrk

2013-07-28 09:22 337 查看
虚拟内存

问题:

一个程序不能访问另外一个程序的地址指向的空间.

理解:

1.每个程序的开始地址0x80084000

2.程序中使用的地址不是物理,而是逻辑地址(虚拟内存).

逻辑地址仅仅是编号.编号使用int 4字节整数表示.

4294967296

每个程序提供了4G的访问能力

问题:

逻辑地址与物理地址关联才有意义:过程称为内存映射.

背景:

虚拟内存的提出:禁止用户直接访问物理存储设备.

有助于系统的稳定.

结论:

虚拟地址与物理地址映射的时候有一个基本单位:

4k 1000 内存页.

段错误:无效访问.

合法访问:比如malloc分配的空间之外的空间可以访问,但访问非法.

虚拟内存的分配.

栈:编译器自动生成代码维护

堆:地址是否映射,映射的空间是否被管理.

1.brk/sbrk内存映射函数

分配释放内存:

intbrk(void *end);//分配空间,释放空间

void*sbrk(int size);//返回空间地址

应用:

1.使用sbrk分配空间/size为正 分配空间 size为负 可释放空间

2.使用sbrk得到没有映射的虚拟地址.

3.使用brk分配空间

4.使用brk释放空间

理解:

sbrk(int size)

sbrk与brk后台系统维护一个指针.

指针默认是null.

调用sbrk,判定指针是否是0,是:得到大块空闲空间的首地址初始化指针.同时把指针+size

否:返回指针,并且把指针位置+size

例子:Linux下

代码1:

#include<stdio.h>

#include<unistd.h>

void main()

{

int * p1=sbrk(0); //得到大块空闲空间的首地址初始化指针

int * p2=sbrk(4); //分配4个字节的空间先返回空闲空间的首地址,在将指针加4

int * p3=sbrk(4); //同理,返回的指针地址为上一次sbrk返回的地址+size

printf(“%p\n”,p1);

printf(“%p\n”,p2);

printf(“%p\n”,p3);

}

运行结果:

0x9d9d000 sbrk(0)返回的空闲空间首地址

0x9d9d000 sbrk(0)返回的空间地址,并把地址+size(0x9d9d004)0x9d9d000-0x9d9d004为sbrk(4)分配的4个字节的空间

0x9d9d004 再次调用sbrk(4),返回的指针为地址0x9d9d004,指针再次+size

0x9d9d004-0x9d9d008为这次调用sbrk分配的4个字节的空间

代码2:

#include<stdio.h>

#include<unistd.h>

void main()

{

int* p=sbrk(0); //返回空闲空间的首地址,但系统并没有给虚拟内存映射物理内存

*p=800; //会出现段错误,无法访问p指向的地址的空间

brk(p+1); //brk(p+1) 是把p指针向后移了4个字节,系统把虚拟内存映射到了//物理内存(映射了一个页的物理内存4k),brk分配了4个字节的//动态内存空间

*p=800; //不会出现段错误

brk(p); //brk(p)又把指针向回移了4个字节,释放了4个字节的空间

*p=800; //则不能再访问p的空间

}

应用案例:

写一个程序查找1-10000之间所有的素数.

并且存放到缓冲,然后打印.

缓冲的实现使用sbrk/brk

流程:

循环

判定是否素数(isPrimer)

是,分配空间存放

不是,继续下步.

代码:

#include<stdio.h>

#include<unistd.h>

int isprimer(int a)

{

intI;

for(i=2;i<a;i++)

{

if(a%i==0)

return 1;

else

return 0;

}

}

void main()

{

int i=2;

int *p=sbrk(0);

int *r;

r=p;

for(;i<1000;i++)

{

if(isprimer(i)==0)

{

brk(r+1);

*r=i;

r=sbrk(0);

}

}

r=p;

while(r!=sbrk(0))

{

printf(“%d\n”,*r);

r++

}

}

brk(p); //free

brk/sbrk

异常处理

intbrk(void*)

void*sbrk(int);

如果成功.brk返回0 sbrk返回指针

失败 brk返回-1 sbrk返回(void*)-1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: