Day25_sbrk()、mmap()

本文探讨了内存管理中的关键概念,如malloc(), sbrk(), brk(), mmap()等函数的作用及使用方法,并介绍了系统调用的概念及其在Unix/Linux系统中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2013年11月05日 星期二 10时16分38秒
-----------------------------------------------------------
i=100,&i=0xbfa6787c

  1 #include <stdio.h>
  2
  3 int main()
  4 {
  5     int* p = (int*)0xbfa6787c;
  6     printf("*p=%d\n",*p);
  7 }
该程序会引发段错误
-----------------------------------------------------------
  malloc()分配的内存在堆中,除了分配内存之外,还要额外占用一些空间,存储 附加数据。附加数据用于辅助操作系统管理内存。比如free()就需要知道内存的大小。附加数据是由 底层的双向链表维护
  malloc()在申请少量内存时 一次映射33个内存页,如果申请大量内存(超过31个内存页)会分配比申请的内存稍多的内存页数。
  free() 不一定会接触内存的映射,最后33个内存页不会接触映射,free()的真正作用是让内存可以重复使用(内存由不可用变为可用)
 
  经验:
    虽然malloc()一次映射33个内存页,会让内存越界不会引发错误,但尽量不要越界,否则可能破坏下一个变量的附加数据
-----------------------------------------------------------
    sbrk()和brk() - Unix/Linux的系统函数
      sbrk()和brk()是通过底层维护的一个位置来管理内存的
      void* sbrk(int increment)
        参数increment为正,代表申请内存,位置向后移动increment字节,扩大数据区
        为0,位置不动,返回当前的位置地址                                                                                                                                                                            
        为负数,代表释放内存,位置向前移动increment字节,缩小数据区
        返回的是移动之前的位置

   sbrk()/brk() 是系统函数,没有malloc()那么复杂
   sbrk()对分配内存简单,释放内存繁琐:brk()正好相反
   int brk(void* pos)
    pos是新的位置,不论以前位置在哪里,直接回到新位置,成功返回0,失败返回-1
   练习:
     使用sbrk()申请内存,使用brk()释放内存,实现存储一个int,一个double和一个字符串
     结论:使用sbrk()申请内存,brk()释放内存最佳
-----------------------------------------------------------     
  mmap() 和 munmap()
   权限、选项的拼接,用 位或| 即可
   void* mmap(void* addr,size_t size,int prot,int flags,int fd,int off)
   参数:addr 一般为NULL,内核选择映射首地址
         size 映射的大小,不足一个内存页会补齐
         prot 权限,固定PROT_READ|PROT_WRITE
         flags 选项,常见以下值:
               MAP_PRIVATE     MAP_SHARED  必选其一,对内存没有区别,对文件有区别
               MAP_ANONYMOUS  匿名映射,代表映射物理内存
   返回映射的首地址,失败返回MAP_FAILED
   
  系统调用:
    用户空间的程序不能直接访问内核空间,但很多功能都必须进入内核空间。Unix/Linux系统在POSIX规范中定义了一系列系统函数,用于 进入内核空间,这些系统函数 叫系统调用(System call)
    系统调用是用户空间和内核空间的桥梁。但频繁调用也会影响性能
    
  文件:
    标C中,关于文件的函数有哪些?
   fopen() fread() fwrite() fclose() fseek() fprintf() fscanf() ftell()...
    这些函数都有Unix/Linux系统调用的支持
    
    Linux中,几乎一切都是文件,包括:文件、目录、内存、各种IO设备。因此,对文件的操作函数可以扩展到各种设备。最基本的几个函数:
    open() read() write() close() ioctl()
    Unix/Linux中,用文件描述符代表一个打开的文件,文件描述符 本质就是一个非负整数。但 文件的信息不存在文件描述符中。每个进程都有一个文件描述符总对应表,每个文件描述符对应一张文件表,数据都存在文件表中。
    进程中同时打开的文件描述符总数有限制,为0到OPEN_MAN,Linux能同时打开256个。文件描述符可以重复利用(关闭后即可)。文件描述符0 1 2被系统预先占用,代表标准输入,标准输出和标准错误。用户的文件描述符从 3 开始。

            
      推荐书籍: Unix环境高级编程 第二版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值