Linux——虚拟内存
来源:互联网 发布:美姿堂专业彩妆护淘宝 编辑:程序博客网 时间:2024/06/05 23:56
问题的提出
pro1.c
#include <stdio.h>#include <stdlib.h>main(){int *a=malloc(4);*a=9999;//*(a+1)=1000;//*(a+1000)=10000;printf("%p\n",a);while(1);}
gcc pro1.c -omain1 运行 main1 结果:0x8a01008
pro2.c
#include <stdio.h>#include <stdlib.h>main(){int *a=(int*)0x8a01008;//逻辑地址 没有与之相对应的物理地址 要建立关联才有意义 这个过程就是内存映射printf("%d\n",*a);while(1);}
猜会不会打印9999
gcc pro2.c -omain2 运行 main2 结果:段错误
原因:
一个程序不能访问另外一个程序的地址指向的空间.
理解:
1.每个程序的开始地址0x80084000
2.程序中使用的地址不是物理地址,而是逻辑地址(虚拟内存).
逻辑地址仅仅是编号.编号使用int 4字节整数表示.
4294967296=4G
每个程序提供了4G的访问能力
问题:
逻辑地址与物理地址关联才有意义:过程称为内存映射.
结论:
虚拟地址与物理地址映射的时候有一个基本单位:至少会映射4K
4k 1000 内存页.
段错误:无效访问. 那段内存没有映射
非合法访问:比如malloc分配的空间之外的空间可以访问(没有段错误),但访问非法.因是越界访问
内存访问分两种:一个是可以访问,但不一定是合法的,比如malloc几个字节,
内存会给你映射4K空间,int* p=malloc(0); *(p+1000)=9999;理论说这是可以访问
四。虚拟内存的分配
栈:编译器自动生成代码维护,我们不用关心
堆:我们关心地址是否映射,映射的空间是否被管理。
1.brk/sbrk 内存映射函数
补充:帮助手册
man 节 关键字
1-8 1:Linux系统(shell)指令 man 1 ls;
2:系统函数 man 2 brk;
3:标准C函数 man fopen 一般在2和3节找
7:系统编程帮助 man 7 tcp(icmp;udp;socket)
分配释放内存:
int brk(void *end);//分配空间,释放空间
void *sbrk(int size);//返回空间分配前的地址 然后内存内部当前指针移动size
应用:
1.使用sbrk分配空间 sbrk(非零整数)
2.使用sbrk得到没有映射的虚拟地址.第一次调用sbrk,sbrk(0)得到的是没有映射的虚拟首地址。
3.使用brk分配空间
4.使用brk释放空间
brk.c
#include <stdio.h>#include <unistd.h>main(){/*int *p=sbrk(0);没有映射空间的虚拟地址*p=8888;*/ //会出现段错误int *p1=sbrk(4);//分配4个字节 映射了一个页 内部当前指针移动4字节*p1=8888;//*(p+1024)=7777;//段错误*(p1+1023)=7777;//没有段错误printf("%d\n",*p1);}
应用案例:
写一个程序查找1-10000之间所有的素数.见demo1.c
并且存放到缓冲,然后打印.
缓冲的实现使用sbrk/brk
流程:
循环
判定是否素数(isPrimer)
是,分配空间存放
不是,继续下步.
demo.c
#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}
总结:
智能指针
stl
new
malloc
brk/sbrk比较适合大空间
异常处理
int brk(void*)
void *sbrk(int);
如果成功.brk返回0 sbrk返回指针
失败 brk返回-1 sbrk返回(void*)-1
memerr.c
#include <string.h>#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <stdio.h>extern int errno;int main(){void *p=sbrk(1000000000*3);if(p==(void*)-1){//perror("Hello:");//printf("Memory:%m\n");printf("::%s\n",strerror(errno));}}
Unix函数错误,修改内部变量:errno
字符串函数string.h cstring
内存管理函数malloc memset mamcmp memcpy ...
bzero
错误处理函数
标准IO函数
时间函数
类型转换函数
- Linux——虚拟内存
- linux之旅——关于虚拟内存
- 操作系统面试—虚拟内存
- Linux初学——设置启动载入、建立虚拟内存
- linux虚拟内存
- linux虚拟内存
- linux虚拟内存
- Linux 虚拟内存
- linux虚拟内存
- Linux虚拟内存
- Linux虚拟内存
- linux虚拟内存
- 基础知识——虚拟内存概念
- 内存管理——虚拟内存
- 进程虚拟内存——简介
- 操作系统——虚拟内存管理
- 存储管理——虚拟内存
- Redis之——虚拟内存
- 下拉菜单
- IOS学习笔记29—提示框第三方库之MBProgressHUD
- Host SMBus controller not enabled的解决方法
- oracle 存储过程中变量名和表的字段名同名时,优先将字段名当做表的字段名
- 九度oj-1008-最短路径问题
- Linux——虚拟内存
- ZOJ Problem Set - 1203
- hdu 3068最长回文子串
- Android应用程序的编译和打包
- C++11(4):语句
- C++ 中list 类模板的简易实现
- 第十一章 11.3.2节练习
- mybatis与hibernate区别
- libpcap的安装、工作原理及流程(引用综合)