🧠 C++ 程序运行时内存布局
📌 适用于理解全局变量、栈、堆、静态区、代码段的存储位置与生命周期。
本文我们主要介绍 C++ 程序运行时内存布局,以及变量存储位置,包括栈、堆、静态存储区等,并附上 ASCII 图解。
🖼️ 内存布局示意图(ASCII 图)
1  | 高地址  | 
🔍 各内存区域详解
1️⃣ 栈(Stack)
- 位置:高地址 → 向低地址增长
 - 内容:
- 局部变量
 - 函数参数
 - 返回地址
 
 - 管理方式:编译器自动分配/释放
 - 生命周期:函数作用域,离开函数后自动释放内存
 - 特点:快、安全、容量小(通常几 MB)
 
1  | void func(int a) { //函数参数 ← 存在栈上  | 
📌 我们常说栈内存是函数调用栈,函数调用时,参数、局部变量会压入栈中,函数返回时,参数、局部变量会从栈中弹出。
2️⃣ 堆(Heap)
- 位置:静态区之上,栈之下 → 向高地址增长
 - 内容:
new/malloc分配的对象- 动态数组、对象、容器底层存储等
 
 - 管理方式:手动 
delete/free或使用智能指针(推荐) - 生命周期:由程序员控制
 - 特点:慢、灵活、容量大
 
1  | int* p = new int(42); // ← p指向对象在堆,p 指针变量在栈  | 
3️⃣ 静态存储区(Data Segment)
➤ .data 段
- 存放已初始化的全局变量和静态变量
 - 示例:
 
1  | int global_var = 999; // ← .data  | 
➤ .bss 段
- 存放未初始化或初始化为 0 的全局/静态变量
 - 示例:
 
1  | int uninit_global; // ← .bss(默认=0)  | 
💡 为什么分
.data和.bss?.data需保存初始值 → 占用可执行文件空间;.bss只需记录大小 → 加载时清零 → 节省磁盘空间。
4️⃣ 代码段(.text)
- 内容:程序的机器指令(函数体)
 - 属性:只读、不可修改
 - 示例:
 
1  | int main() { return 0; } // ← 函数代码存在 .text 段  | 
🧭 地址增长方向示意
1  | 高地址 ────────────────┐  | 
⚠️ 实际地址分布可能因操作系统、编译器、架构略有不同,但“栈向下、堆向上”是常见模型。
🧪 示例代码 + 地址输出示意
1  | 
  | 
📌 典型输出地址顺序(64位 Linux 示例):
1  | global_data: 0x555555558010 ← .data(低地址区)  | 
✅ 总结口诀
“代码垫底,数据居中,堆往上爬,栈往下降,全局静态稳如泰山。”
📚 附:变量存储位置速查表
| 变量类型 | 存储位置 | 生命周期 | 是否需要手动管理 | 
|---|---|---|---|
| 全局变量 | 静态区(.data/.bss) | 整个程序运行期 | ❌ 否 | 
| 静态局部变量 | 静态区 | 整个程序运行期 | ❌ 否 | 
| 局部变量 | 栈 | 函数作用域 | ❌ 自动管理 | 
new / malloc 对象 | 
堆 | 手动控制 | ✅ 是(或智能指针) | 
| 函数代码 | 代码段(.text) | 整个程序运行期 | ❌ 只读不可修改 | 
📌 学习建议:配合调试器(如 GDB)或打印变量地址,亲自观察内存分布,理解更深刻!
- 本文作者: 迪丽惹Bug
 - 本文链接: https://lyroom.github.io/2025/09/19/C-程序运行时内存布局/
 - 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!