| 區域 | 存儲內容 | 管理方式 | 生命週期 |
|---|---|---|---|
| 棧 | 局部變量、函數參數、返回地址 | 編譯器自動分配/釋放 | 函數結束自動銷毀 |
| 堆 | 動態分配內存(new/malloc) | 程序員手動管理 | 手動釋放或程序結束由 OS 回收 |
| 全局/靜態區 | 全局變量、靜態變量(static) | 編譯時分配 | 程序全生命週期 |
| 常量區 | 字符串字面值、const 修飾的常量 | 編譯時分配 | 程序全生命週期,通常只讀 |
| 代碼區 | 二進制機器指令 | 編譯時生成 | 程序全生命週期,只讀 |
| 維度 | 棧 | 堆 |
|---|---|---|
| 提供者 | 系統(CPU 指令支持) | C/C++ 運行時庫 |
| 效率 | 極高(指針移動) | 較低(鏈表查找/合併) |
| 靈活性 | 固定大小、LIFO | 任意大小、任意順序分配釋放 |
| 碎片 | 無 | 有(外部碎片) |
| 生長方向 | 向下(高地址→低地址) | 向上(低地址→高地址) |
| 唯一性 | 每線程一個 | 進程可有多個堆 |
int a = 0; // 全局初始化區
char *p1; // 全局未初始化區 (BSS)
int main() {
int b; // 棧
char s[] = "abc"; // 棧 (數組內容拷貝自常量區)
char *p2; // 棟 (指針變量本身)
char *p3 = "123456"; // "123456\0" 在常量區,p3 在棧
static int c = 0; // 全局/靜態初始化區
p1 = new char[10]; // 堆分配 10 字節
p2 = new char[20]; // 堆分配 20 字節
strcpy(p1, "123456"); // 字符串拷貝到堆,"123456\0" 仍在常量區
// 編譯器可能優化:p1 和 p3 指向同一常量區地址
}
delete/freenullptrnullptr結構體成員按聲明順序排列,編譯器插入填充字節滿足對齊要求(通常為成員大小或編譯器默認對齊數)。可用 #pragma pack(n) 或屬性 __attribute__((packed)) 控制。
理解五大內存區特性,掌握棧堆差異,是寫出高效、穩健 C/C++ 代碼的基礎。實戰中:優先用棧(RAII、智能指針)、謹慎用堆、少用全局、常量區只讀。