堆、栈、静态区、常量区、自由存储区一次讲清
很多人第一次在面试里听到'内存模型'会懵——以为在问大小端,或者把'堆/栈/全局区/常量区/代码区'背一遍就完了。 真正卡人的点在于:你看到的'5 个区域'并不是 C++ 标准定义的唯一划分;网络上常额外引入'自由存储区',于是概念开始互相打架
0. 为什么越看越乱?
你可能见过类似下面两段(很多博客/笔记都会这么写):
- 'C++ 内存分 5 个区域:堆、栈、全局/静态区(.data/.bss)、常量区(.rodata)、代码区(.text)'
- '根据对象生命周期,内存模型有三种:自由存储区/动态区/静态区……(还有'局部非静态变量 (栈)'塞进同一条)'
问题在于:它们混用了两个维度:
- OS / 可执行文件 / 进程地址空间的'段与区域'(
.text/.data/.bss/.rodata/stack/heap/...) - C++ 语言层面对象的存储期(lifetime / storage duration)(自动、静态、动态、线程)
这两个维度是'映射关系',不是'包含关系'。
所以:不存在'代码区里还有静态区/动态区';.text就是放指令的,静态/动态讲的是对象生命周期或分配方式。
1. 面试建议答案
C++ 里常用两种视角来描述内存:
- OS/二进制段视角(实现相关):程序加载到内存后通常包含
.text:代码段(通常只读 + 可执行).rodata:只读数据(字符串字面量、部分常量等,具体看编译器/平台).data:已初始化的全局/静态数据.bss:零初始化/未显式初始化的全局/静态数据- 运行时还有
stack(栈)和heap(堆)等
- C++ 对象存储期视角(标准更关心这个):
- 自动存储期:局部变量/参数(通常在栈)
- 静态存储期:全局变量、
static变量(常在.data/.bss,只读的可能在.rodata) - 动态存储期:
new/delete管理(自由存储区 free store,通常由堆/内存池等实现) - 线程存储期:
thread_local(TLS)
补一句区分点:heap 常指 malloc/free 的分配来源;free store 指 operator new/delete 管的内存,两者常重合但不必须相同。
2. 看到的'5 类 + 自由存储区'到底该怎么理解?
你列的这几类:
- 堆:
malloc/free - 栈:局部变量
- 全局/静态存储区:全局变量、静态变量
- 常量存储区:常量
- 自由存储区:
new/delete
正确解读方式是:它们不是严格互斥的五块地,而是不同层级的叫法。
2.1 栈(stack)
- 是什么:线程调用栈,保存调用帧(返回地址、保存寄存器、局部变量等)
- C++ 对应:自动存储期对象(局部非
static)


