C/C++程序的5种内存存储区及示意

操作系统中的内存一般分为虚拟内存和物理内存,本文主要讨论的是虚拟内存中的内存分配方式与内存存储区的内容。

内存分配方式

  • C/C++主要有以下五种内存存储区:
    • 全局/静态存储区域:存全局变量,静态变量。程序编译时内存已分配好,并存在于程序整个运行期间,程序结束后由系统统一释放
      • 全局变量和静态变量被分配到同一块内存中。
        • C 语言中,全局变量又分为初始化的和未初始化的。初始化的全局变量和静态变量在一块区域,未初始化的全局变量与静态变量在相邻的另一块区域。同时未被初始化的对象存储区可以通过 void* 来访问和操纵,程序结束后由系统自行释放。
        • 在 C++ 里面没有区分,他们共同占用同一块内存区。
    • :存放函数的参数值,局部变量,函数执行结束时会被自动释放。栈内存分配运算内置于处理器的指令集中,效率高,但是容量有限。
    • 堆(动态内存分配)通过new和malloc由低到高分配,由delete或free手动释放或者程序结束自动释放。动态内存的生存期人为决定,使用灵活。缺点是容易分配/释放不当容易造成内存泄漏,频繁分配/释放会产生大量内存碎片。 若程序员不释放,程序结束时可能由OS(操作系统)回收
    • 字符/文字常量区: 存放常量字符串,程序结束时由系统释放
    • 程序代码区: 存放函数体的二进制代码

内存存储区示意图

下图参考[1],地址由低到高可以分为:
C/C++程序的5种内存存储区及示意

  • Unused Memory:
  • Read-only code segment:只读,存代码和一些其他的东西
  • Read/Write data segment:
    • .data:存初始化的全局变量和static变量,另外还有文字常量区,常量字符串就是放在这里,程序结束后有系统释放
    • .bss:存未初始化的全局变量和static变量
  • Heap通过new和malloc由低到高分配,由delete或free手动释放或者程序结束自动释放
  • Shared libraries:调用的库文件,位于堆和栈之间
  • Stack由高向低增长,和堆的增长方式相对,对不同的OS来说,栈的初始大小有规定,可以修改,目前默认一般为2M,由编译器自动分配释放
  • Kernel virtual memory:用户不可见不能访问

References:

  1. Computer Systems: A Programmer’s Perspective, 3/E (CS:APP3e)
  2. C/C++内存分配方式与存储区
  3. 程序在内存中的分布