三.内存映射
映射相对底层的内存管理方式。
控制内存的权限。
控制内存映射到文件
1.函数说明:
a.mmap映射内存
void mmap(
void *start,//从指定位置开始映射,必须是页首
//如果为0/NULL,系统指定开始映射地址
size_t size,//映射的大小,建议page倍数
int prot,//指定映射权限
//PROT_READ,PROT_WRITE,PROT_EXEC,PROT_NONE
int flags,//映射方式
//MAP_SHARED MAP_PRIVATE
//MAP_ANONYMOUS 内存映射。否则是文件映射
int fd,//只对文件映射有效
off_t off//问价你映射的开始位置,必须是page的倍数
);
b.mumap卸载映射
void munmap(void *start,size_t length);
练习:
1.使用brk/sbrk打印1-20000之间的孪生素数.
2.使用new/malloc/brk/mmap分配空间,观察分配规律
3.使用new/malloc/brk/mmap分配空间,观察/proc/$pid/maps
每个内存在那个段?
思考:
4.理解内存.
#include <stdio.h>
#include <unistd.h>
main()
{
int *p=sbrk(4);
int *p2=sbrk(4);
int *p3=sbrk(4);
printf("%x ",p);
printf("%x ",p2);
printf("%x ",p3);
}
用sbrk判断素数
#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 *pstart=sbrk(0);
int *p;
p=pstart;
int i;
for(i=2;i<10000;i++)
{
if(!isprimer(i))
{
brk(p+1);
*p=i;
p=sbrk(0);
}
}
int *pend=sbrk(0);
p=pstart;
while(p!=pend)
{
printf("%d ",*p);
p++;
}
brk(pstart);
}
函数指针
#include <stdio.h>
int add(int a,int b)
{
return a+b;
}
int sub(int a,int b)
{
return a-b;
}
main()
{
typedef int (*addfunc)(int,int);
printf("%x ",main);
printf("%x ",&main);
int (*padd)(int,int);
padd=(int(*)(int,int))add;
addfunc a;
a=add;
/*
padd=add;
padd=*add;
padd=&add;*/
int r=padd(45,55);
printf("%d ",r);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
/*
#define NULL (void*)0
*/
main()
{
char*str=mmap(
0,//
1*getpagesize(),//
PROT_READ|PROT_WRITE,//
MAP_SHARED|MAP_ANONYMOUS,//
0,0);
memset(str,0,1*getpagesize());
memcpy(str,"Hello World!",12);
printf("%s ",str);
munmap(str,1*getpagesize());
}
int *p=(int*)realloc(c,20);
#include <stdio.h>
#include <unistd.h>
main()
{
int *p=sbrk(0);
brk(p+1);
*p=10;
brk(p);
*p=20;