🧩 C 程序的内存分区结构
一个典型的 C 程序在运行时,内存大致分为以下几个区域:
| 区域 | 内容 | 特点 |
|---|---|---|
| 代码区 (Text Segment) | 程序的机器指令 | 只读 |
| 全局/静态区 (Data Segment) | 已初始化的全局变量和静态变量 | 程序运行期间存在 |
| 常量区 (Read-Only Data Segment) | 字符串常量、const 常量 |
只读,禁止修改 |
| 栈区 (Stack) | 局部变量、函数参数、返回地址 | 自动分配释放 |
| 堆区 (Heap) | malloc / free 分配的内存 |
动态分配释放 |
🧠 各内存区域详解
1️⃣ 代码区 (Text Segment)
- 存放程序的可执行代码(机器指令)。
- 一般是 只读的,防止程序意外修改自身。
- 典型内容:函数体、
main()的指令。
2️⃣ 全局/静态区 (Data Segment)
分为两类:
- 已初始化数据段 (.data):存放已初始化的全局/静态变量。
- 未初始化数据段 (.bss):存放未初始化的全局/静态变量,程序启动时自动清零。
生命周期:从程序启动到结束。
3️⃣ 常量区 (Read-Only Data Segment)
- 存放字符串常量和const 修饰的常量。
- 通常是只读的,修改会导致段错误。
- 示例:
char *s = "hello";的"hello"就放在这里。
4️⃣ 栈区 (Stack)
- 用于存放函数的局部变量、参数、返回地址等。
- 由系统自动分配和释放。
- 特点:后进先出 (LIFO)。
- 超出函数作用域后自动销毁。
5️⃣ 堆区 (Heap)
- 程序运行时通过
malloc()、calloc()、realloc()等动态申请的内存。 - 由程序员手动释放(通过
free())。 - 若未释放,容易造成 内存泄漏。
⚙️ 内存生命周期对比
| 区域 | 分配方式 | 释放方式 | 生命周期 |
|---|---|---|---|
| 代码区 | 编译时 | 程序结束 | 整个程序运行期间 |
| 全局/静态区 | 编译时 | 程序结束 | 整个程序运行期间 |
| 常量区 | 编译时 | 程序结束 | 整个程序运行期间 |
| 栈区 | 自动 | 自动(函数返回时) | 函数调用期间 |
| 堆区 | 手动 (malloc) |
手动 (free) |
程序员控制 |
💡 总结记忆口诀
“代全常栈堆” 五区口诀:
- 代码区:存放机器指令;
- 全局/静态区:变量全局共享;
- 常量区:常量不可改;
- 栈区:函数自动分配;
- 堆区:手动申请释放。
✅ 小贴士
- 栈区通常内存较小(如几 MB),而堆区空间大。
- 全局变量和静态变量只初始化一次。
- 字符串常量放在常量区(不可修改)。
- 局部变量在栈区,函数返回后内存失效。