Linux系统内存管理API

Linux系统内存管理API

遵循POSIX标准的内存管理API:
#include <unistd.h>
​
//  brk和sbrk在内部维护一个指针p(void*),p指针指向当前堆内存中已经映射成功的最后一个字节的下一个地址位置
void *sbrk(intptr_t increment);
功能:根据参数increment来调整p的位置,既可以映射内存,也可以取消映射
incremen:移动增量
    >0  p+incremen  映射内存
    0   p           获取p的位置
    <0  p+incremen  取消映射
返回值:移动前,p指针的位置  
​
int brk(void *addr);
功能:通过直接移动p到addr地址位置,来映射和取消映射
addr:   直接移动到的位置
    > p     映射内存
    < p     取消映射    
返回值:成功0 失败-1
    
注意:sbrk和brk都可以单独映射、取消映射,但是一般都会配合一起使用,通过sbrk映射内存,通过brk取消映射
注意:sbrk和brk只能对虚拟内存进行映射、取消映射,无法做到精细化管理,只是维护一个位置指针

练习:计算出100~100000之间的所有素数,存储在堆内存,尽量不浪费内存

#include <stdio.h>      
#include <unistd.h>
#include <stdbool.h>
​
bool is_prime(int num)
{
    for(int i=2; i<=num/2; i++)
    {
        if(0 == num%i) return false;
    }
    return true;
}
​
int main(int argc,const char* argv[])
{
    int* start = sbrk(0);
    for(int i=100; i<100000; i++)
    {
        if(is_prime(i))
        {
            int* p = sbrk(4);
            *p = i;
        }
    }
​
    int* p = start,*end = sbrk(0);
    while(p < end)
    {
        printf("%d ",*p++);
    }
    brk(start);
}
Linux系统提供的内存管理函数:
#include <sys/mman.h>
//  mmap和munmap底层不维护任何东西
//  通过mmap映射内存,是以一页为单位来映射的
​
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
功能:
    1、用户空间的虚拟内存与物理内存建立映射关系
    2、用户空间的虚拟内存与文件建立映射关系
addr:想要映射的虚拟内存的首地址,如果是NULL,则由操作系统自动计算
length:要映射的字节数
prot:映射后的内存权限
    PROT_EXEC  执行权限  
    PROT_READ  读权限  
    PROT_WRITE 写权限     
    PROT_NONE  无权限  
        如果要有多个权限,进行按位或操作
flags:设置参数
    MAP_SHARED  共享映射,映射的内容对其它进程是可见的,如果此时映射给文件,相当于可以输出到文件中
    MAP_PRIVATE 私有映射,映射的内容其它进程不可见
    MAP_ANON    拒绝对文件进行映射,会忽略fd、offset参数
    MAP_FIXED   如果提供了addr无法进行映射,则直接失败,系统不会自动调整
fd:文件描述符,类似于文件指针,如果不使用则给0即可
offset:映射文件后从该偏移值开始操作文件
返回值:映射成功后的虚拟内存首地址,失败返回0xFFFFFFFF
​
int munmap(void *addr, size_t length);
功能:取消映射
addr:已经映射的内存首地址
length:内存字节数
返回值:成功0 失败-1
#include <stdio.h>                                                                                                                                              
#include <sys/mman.h>
​
int main(int argc,const char* argv[])
{
    FILE* fp = fopen("t.txt","r+");
    if(NULL == fp)
    {
        perror("fopen");
        return -1;
    }
​
    //  转换成文件描述符
    int fd = fileno(fp);
​
    printf("----\n");
    char* str = mmap(NULL,100,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_FILE,fd,0);
    printf("----\n");
    if((void*)-1 == str)
    {
        perror("mmap");
        return 0;
    }
    //  往映射后的虚拟内存写入数据 
    printf("----%s\n",str);
    sprintf(str,"hello worldxxxxxxxxxxiid\n");
//  str[0] = 'a';   
    //  取消映射
    munmap(str,100);
​
    fclose(fp);
}

  • 34
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值