🔍 記憶體中的 Stack 與 Heap 教學 在程式執行期間,記憶體會依用途分成不同區塊,其中最常見的就是 Stack 和 Heap。它們用途不同,管理方式也不同,了解它們對於寫出穩定、高效的程式碼至關重要。 一、Stack(堆疊) 🔹 定義 Stack 是一種**先進後出(LIFO, Last In First Out)**的記憶體區塊,用來儲存: 函式的參數 區域變數 返回位址(return address) 🔹 特點 特點 說明 生命週期 自動管理,函式呼叫時配置,函式結束時自動釋放 存取速度 快速(因為使用指標遞增/遞減) 大小限制 較小(通常幾MB) 安全性 靠近系統,容易造成 stack overflow(堆疊溢位) 🔹 示意圖 c 複製 編輯 void func() { int a = 10; // 存在 stack 中 } 當 func() 被呼叫時,a 就會被壓入 stack,等 func() 結束時,自動釋放。 二、Heap(堆積) 🔹 定義 Heap 是由開發者自行控制的記憶體區域,適合儲存需要跨函式或長時間存在的資料。需使用 malloc, new, 或其他動態配置函式取得。 🔹 特點 特點 說明 生命週期 需開發者手動配置與釋放 存取速度 較慢(需查表和指標跳轉) 大小限制 大(數百MB到GB,視系統而定) 容易問題 記憶體洩漏(Memory Leak)、野指標、重複釋放等問題 🔹 示意圖 c 複製 編輯 int* p = (int*)malloc(sizeof(int)); *p = 100; free(p); 變數 p 存的是 heap 的位址,使用完要記得 free 釋放,否則會造成 memory leak。 三、Stack 與 Heap 的比較 比較項目 Stack Heap 管理方式 編譯器自動管理 程式設計師手動管理 存取速度 快 慢 空間大小 小(幾MB) 大(幾百MB~GB) 生命週期 函式範圍內 可跨函式、動態決定 出錯風險 Stack overflow 記憶體洩漏、錯誤釋放 四、為什麼要分 Stack 與 Heap? 效率考量:快速配置/釋放 → 放在 Stack 靈活性:需要更大空間、動態配置 → 放在 Heap 責任劃分:Stack 編譯器管理;Heap 程式設計師管理 五、常見錯誤案例 1. Stack Overflow c 複製 編輯 void recursive() { int arr[10000]; recursive(); // 無限遞迴,堆疊不斷成長 → crash } 2. Heap Memory Leak c 複製 編輯 void func() { int* p = (int*)malloc(sizeof(int)); // 沒有 free(p); → 記憶體洩漏 } 六、結論與建議 建議 說明 使用 Stack 優先 小資料、短生命週期變數優先放 Stack 使用 Heap 要記得釋放 避免記憶體洩漏 工具協助除錯 如:Valgrind、AddressSanitizer
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up