高位址
+-------------------+
| 核心空間 | (用戶程式不可訪問)
+-------------------+
| 使用者棧 | ← 向下增長 (堆疊區)
| ↓ |
| . |
| . |
| ↑ |
| 堆積區 | ← 向上增長 (動態分配)
+-------------------+
| BSS 段 | 未初始化全域/靜態變數
| Data 段 | 已初始化全域/靜態變數
| Text 段 | 程式碼、唯讀常數
+-------------------+
低位址
| 維度 | 堆疊 | 堆積 |
|---|---|---|
| 管理方式 | 編譯器自動管理 | 程式設計師手動管理 (malloc/free, new/delete) |
| 空間大小 | 固定、較小 (Windows 預設 1-2MB) | 動態、大 (受限於虛擬記憶體,可達 GB) |
| 分配速度 | 極快 (指標移動) | 較慢 (鏈結串列搜尋/分配器演算法) |
| 記憶體分佈 | 連續 | 不連續 (透過指標/鏈結串列管理) |
| 碎片問題 | 無 | 易產生外部碎片 |
| 存取效率 | 高 (連續、快取友善) | 較低 (間接寻址) |
| 生命週期 | 作用域結束自動銷毀 | 手動控制,跨函式共享 |
| 失敗模式 | 棧溢位 | 分配失敗回傳 NULL / 拋出 bad_alloc |
char c; // 編譯器檢查剩餘空間 → 移動 ESP → 完成
char *p = new char[3]; // p 在堆疊,指向堆積記憶體
函式呼叫時:返回位址 → 參數 (右至左) → 區域變數 → 舊 EBP。返回時逆序彈出。
大小 | 狀態 | 下一塊指標malloc 遍歷鏈結串列找第一塊滿足大小的區塊,分割、標記、回傳位址。free 標記釋放,嘗試與相鄰空閒塊合併 (防碎片)。char a = 1;
char c[] = "1234567890"; // 堆疊陣列
char *p = "1234567890"; // 指向常數區/堆積
a = c[1]; // mov cl, [ebp-0Fh] ; mov [ebp-4], cl (直接位址存取)
a = p[1]; // mov edx, [ebp-14h] ; mov al, [edx+1] ; mov [ebp-4], al (間接: 先取指標再取值)
堆疊陣列:單指令直接存取。指標:雙指令 (載入基址 + 位移存取)。差異在緊迴圈中會被放大。
繞過堆積分配器,直接向作業系統申請頁面對齊的虛擬記憶體區域。
優點:速度快、無碎片、可設定保護屬性 (PAGE_READWRITE, PAGE_GUARD 等)。
缺點:粒度大 (最小 4KB/64KB)、介面複雜、需手動管理。
unique_ptr, shared_ptr) 或容器 (vector, string) 管理堆積資源。/STACK)。堆疊與堆積是記憶體管理的雙支柱。理解其空間佈局、分配演算法、存取指令差異、失敗模式,並遵循「能用堆疊不用堆積、用堆積必用 RAII」原則,是寫出高效、穩健 C/C++ 程式的核心功力。