C与C++的内存分布

前言

关于C与C++的内存分布这个,我一直很迷糊,这次决定写一篇博客来记录一下。
参考博客为:[http://harlon.org/2018/04/21/cpluscplusmemory/]

C程序内存布局

C与C++的内存分布
C程序的内存空间布局如上图所示,分为内核空间和用户空间。内核空间主要包括一些进程相关的信息等,用户空间就是一些与程序本身相关的信息。
用户空间主要分为以下几个部分:

  • 文本段(Text)
  • 数据段(Data)
  • BSS段
  • 堆(Heap)
  • 栈(Stack)
文本段(Text)

分成 RO DATACode段,Code段存放程序指令,RO DATA段存放全局常量、字符串常量。

可执行文件的文本段包含程序的指令,链接器把指令直接从可执行文件拷贝到内存中,形成文本段。


数据段(Data)

存放已初始化的全局变量static 变量。

可执行文件的数据段包含经过初始化的全局和静态变量以及它们的值。


未初始化数据段(BSS段)

存放未初始化的全局变量static 变量。

未初始数据段也称之为BSS段,即Block Started by Symbol,在BSS段中存放的数据都是未被初始化的全局变量和静态变量,并默认会把这部分数据初始化为0。


动态内存分配区,由程序员控制,存放动态分配的变量。

向高地址增长,堆中分配内存和释放内存需要调用malloc/new或free/delete。


保存的是局部变量(包括局部常量)和每次函数调用时的信息。

栈和堆一般相邻,但沿着相反方向增长。当栈指针和堆指针相等就说明堆栈内存耗尽。栈中保存的是局部变量和每次函数调用时的信息。每次函数调用返回地址,一些调用者环境信息(比如寄存器)都被存放在栈中。然后新调用的函数就会在栈中为他们的自动或者临时变量分配内存空间,这就是C中递归函数调用的过程。每次递归函数调用自己,新的堆栈就会被创建,这样新的变量集合就不会被其他函数实例的变量集合影响了。


C++ 内存布局

这里说的C++内存布局与上面的C内存布局是相似的,说的并不是C++的对象内存布局。在C++中内存可以分为以下5个部分:

代码段

保存代码。


常量存储区

存储全局C++常量。


全局/静态存储区

在C++中,不再区分数据段和BSS段,未初始化和初始化的全局/静态变量都会存储在这里。但也有博客说还是会分成data段和bss段,data段保存初始化的,bss段保存未初始化的。


与C程序中的相同,保存动态变量。


与C程序中的相同,保存局部变量。


总结(各类型变量的位置)

段区域 地址空间 存储变量
stack 局部变量和局部常量
heap 动态分配的数据
BSS 未初始化数据段BSS 未初始化的全局变量以及静态变量(全局和局部)
RWDATA 已初始化读写数据段RW data 已初始化的全局变量和静态变量(全局和局部)
RODATA 文本段中的数据段RO data 全局常量或者字符串面变量
code 文本段的程序代码段 code 程序的代码