unix c 学习笔记之内存管理

一,内存管理

在linux系统编程中,主要有以下几种内存分配和释放方式,他们是一一对应的;

mmap/munmap,sbrk/brk,malloc,calloc,realloc/free;

以下是函数的原型:

void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset); 

函数功能:映射一片内存空间或者将一个文件映射到一片虚拟内存空间,直接通过操作内存的方式来操作文件;

第一个参数:指定映射的起始虚拟地址,如果为0,则起始地址由系统指定;

第二个参数:映射的空间的大小,建议为4K的倍数,不是4K的倍数会自动对齐;

第三个参数:映射内存的权限(内存保护方式),PROT_READ,PROT_WRITE,PROT_EXEC依次为 读,写,执行;

第四个参数:内存的标志位,也就是映射模式,MAP_PRIVATE内存私有只能在本进程访问,MAP_SHARED内存共享

MAP_ANONYMOUS 匿名映射,如果使用该标志位,则文件描述符fd,文件开始映射的位置offset会无效.

第五个参数:一个已经打开的文件的描述符,如果进行文件映射,则上一参数不能使用匿名映射选项MAP_ANONYMOUS;

第六个参数:文件开始映射的位置.

int munmap(void *start, size_t length); 用来释放mmap分配的内存

该函数主要用来解除映射,参数分别为要解除的地址,该地址所对应空间的大小;

mmap的一个小例子:

 
 

#include <sys/mmam.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h>

int main() {   int *p;   printf("pid=%d\n",getpid());   //物理内存映射   p=mmap(0,4,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_SHARED,0,0);   //如果映射成功   if(!p)  printf("内存分配失败\n"),exit(0);   printf("成功建立内存映射\n");   *p=8090;   printf("*p=%d\n",*p);   munmap(p,4);   printf("释放OK!\n");   return 0; }

void *sbrk(intptr_t increment);  分配和修改内存,返回上次sbrk/brk后的内存的末尾地址

int brk(void *end_data_segment); 修改内存末尾地址

一个小列子:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
  void *p=sbrk(0); //系统会默认给一个起始地址
  printf("%p\n",p);
  int r=brk(p+4); //将指针p扩充4个字节
  brk(p+8);
  printf("%p\n",p+8);
  *((int*)p)=4;
  *((int*)(p+4))=6;
  //由于sbrk在第一次分配内存时,映射了一个page大小的内存,所以下边的访问不会出现段错误
  *((int*)(p+8))=8;  //没有进行分配,但是可以访问,这种内存存在危险,破坏数据
  if(0==r)printf("修改内存成功!\n");
  else printf("%m\n"); 
  printf("%d******%d********%d\n",*((int*)p),*((int*)(p+4)),*((int*)(p+8)));
  printf("pagesize=%d\n",getpagesize());
 
  //下边两行能正常执行  因为内存地址在pagesize范围内,访问的是已经映射过的内存
  *((int*)(p+4092))=4092; 
  printf("%d\n",*((int*)(p+4092)));
 
  //下边两行出现段错误
  *((int*)(p+4096))=4096; 
  printf("%d\n",*((int*)(p+4096)));
 
  return 0;
}

mmap主要用来分配较大的内存空间,比sbrk/brk底层,而malloc是c的标准库函数,他的底层实现也是用sbrk/brk来实现的,适合分配较小的内存块,

由于malloc分配的内存在系统中以一个链表来维护,这样一来便可以合理利用内存碎片;

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值