| 區段 | 英文 | 內容 | 權限 | 生命週期 | 管理者 |
|---|---|---|---|---|---|
| 程式碼區 | .text | 函數機器碼、常數字串字面值 | R/X | 程式全期 | 作業系統載入器 |
| 唯讀資料區 | .rodata | const 全域/靜態變數、字串常值 | R | 程式全期 | 作業系統 |
| 已初始化資料區 | .data / .rwdata | 非零初始化的全域/靜態變數 | R/W | 程式全期 | 作業系統 |
| 未初始化資料區 | .bss | 零初始化的全域/靜態變數(編譯器自動清零) | R/W | 程式全期 | 作業系統 |
| 堆區 | heap | malloc/new 動態分配記憶體 | R/W | 手動控制 | 程式設計師 / 配置器 |
| 棧區 | stack | 區域變數、函數參數、返回位址、暫存器保存 | R/W | 函數呼叫期間 | 編譯器自動 |
+------------------------+ 0xFFFFFFFF (4GB) | Kernel Space (1GB) | 用戶程式不可直接存取 +------------------------+ 0xC0000000 | Stack ↓ | 向下增長(高位址 → 低位址) | | | | | | | Heap ↑ | 向上增長(低位址 → 高位址) | | +------------------------+ .bss 結束 | .bss (zero) | +------------------------+ .data 結束 | .data (init) | +------------------------+ .rodata 結束 | .rodata | +------------------------+ .text 結束 | .text (code) | +------------------------+ 0x08048000 (典型載入基址)
// main.cpp
int a = 0; // .data (已初始化全域)
char *p1; // .bss (未初始化全域)
int main() {
int b; // Stack (未初始化區域)
char s[] = "abc"; // Stack (陣列內容複製自 .rodata)
char *p2; // Stack (指標變數本身)
char *p3 = "123456"; // p3 在 Stack,"123456\0" 在 .rodata
static int c = 0; // .data (已初始化靜態區域)
p1 = malloc(10); // Heap (10 bytes)
p2 = malloc(20); // Heap (20 bytes)
strcpy(p1, "123456"); // 複製字串常值到 Heap,編譯器可能合併相同常值
free(p1); free(p2); // 歸還 Heap
return 0;
}
| 維度 | Stack(棧) | Heap(堆) |
|---|---|---|
| 管理方式 | 編譯器自動( prologue/epilogue 指令) | 手動 malloc/free 或 new/delete |
| 空間大小 | 有限(Linux 預設 8MB,Windows 1MB,可調整) | 巨大(32-bit 理論 4GB,受虛擬記憶體限制) |
| 碎片問題 | 無(LIFO,永不產生洞) | 嚴重(頻繁分配釋放產生外部碎片) |
| 增長方向 | 向下(位址遞減) | 向上(位址遞增) |
| 分配速度 | 極快(指標加減) | 較慢(尋找合適塊、可能系統調用) |
| 失敗模式 | Stack Overflow(遞迴過深、大型區域陣列) | Allocation Failure(記憶體耗盡、碎片化) |
static 為內部連結,僅本編譯單元可見;普通全域為外部連結,全專案可見(需 extern 宣告)。static 減少符號汙染,避免多檔案命名衝突。同 static 全域變數,限制函數作用域於本編譯單元,實現封裝。注意:static 此處非指儲存類別,而是連結屬性。
char buf[1000000])→ Stack Overflow。✅ 改用 malloc 或 static。malloc/free。snprintf)、編譯器強化(-fstack-protector、FORTIFY_SOURCE)。深入理解記憶體佈局是 C/C++ 系統程式設計師的必修課。從編譯連結產生的 Section,到執行期 Stack/Heap 的動態互動,再到 static/extern 的連結語義,每一層都直接影響程式的正確性、效能與安全性。建議搭配 size、nm、objdump、/MAP 等工具觀察實際輸出,理論結合實驗,方能臻於化境。