C++面試常見題目4_記憶體管理,記憶體洩露
-
記憶體管理
- 定義:記憶體管理是指軟體執行時對計算機記憶體資源的分配和使用的技術。其最主要的目的是如何高效,快速的分配,並且在適當的時候釋放和回收記憶體資源。
-
在C++中記憶體分為5個區,分別是堆、棧、自由儲存區、全域性/靜態儲存區和常量儲存區。
堆:堆是作業系統中的術語,是作業系統所維護的一塊特殊記憶體,用於程式的記憶體動態分配,C語言使用malloc從堆上分配記憶體,使用free釋放已分配的對應記憶體。
棧:在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高,但是分配內容容量有限。
自由儲存區:自由儲存區是C++基於new操作符的一個抽象概念,凡是通過new操作符進行記憶體申請,該記憶體即為自由儲存區。
全域性/靜態儲存區:這塊記憶體是在程式編譯的時候就已經分配好的,在程式整個執行期間都存在。例如全域性變數,靜態變數。
常量儲存區:這是一塊比較特殊的儲存區,他們裡面存放的是常量(const),不允許修改。
- 常見記憶體錯誤及解決方案
-
記憶體未分配成功,但使用它。解決方案:在使用記憶體之前檢測指標是否為空。
-
記憶體分配成功,但尚未初始化就引用了它。解決方案:初始化。
-
記憶體分配成功,但越界訪問。解決方案:迴圈等語句中注意邊界。
-
忘記釋放記憶體,導致記憶體洩露。
-
已經釋放記憶體,但仍然使用它。解決方案:free或delete後,將指標設為NULL,避免產生”野指標“;記憶體函式中return寫錯,返回了指向棧中的指標或引用;程式中物件的關係過於複雜,難以搞清哪個物件是否已經釋放了。
-
記憶體洩露
-
定義:記憶體洩漏(Memory Leak)是指程式中己動態分配的堆記憶體由於某種原因程式未釋放或無法釋放,造成系統記憶體的浪費,導致程式執行速度減慢甚至系統崩潰等嚴重後果。
- 發生方式
-
常發性記憶體洩漏:發生記憶體洩漏的程式碼會被多次執行到,每次被執行時都會導致一塊記憶體洩漏。
-
偶發性記憶體洩漏:發生記憶體洩漏的程式碼只有在某些特定環境或操作過程下才會發生。
-
一次性記憶體洩漏:發生記憶體洩漏的程式碼只會被執行一次,或由於演算法上的缺陷,導致總會有一塊且僅有一塊記憶體發生洩漏。
-
隱式記憶體洩漏:程式在執行過程中不停的分配記憶體,但是直到結束的時候才釋放記憶體。
- 檢測方法
- 靜態分析技術
- 原始碼插裝技術
- 目的碼插裝技術
- 被測程式碼預處理
- 測試執行階段
- 資料統計與結果彙總
檢測工具
- MS C-Runtime Library內建的檢測功能;
- 外掛式的檢測工具,諸如,Purify,BoundsChecker等;
- 利用Windows NT自帶的Performance Monitor。
- 這三種工具各有優缺點,MS C-Runtime Library雖然功能上較之外掛式的工具要弱,但是它是免費的;Performance Monitor雖然無法標示出發生問題的程式碼,但是它能檢測出隱式的記憶體洩漏的存在,這是其他兩類工具無能為力的地方。
- 記憶體溢位
- 記憶體溢位是指應用系統中存在無法回收的記憶體或使用的記憶體過多,最終使得程式執行要用到的記憶體大於虛擬機器能提供的最大記憶體。記憶體溢位可能是記憶體洩露引起的。
本系列文章目的為個人準備面試的簡單總結,文中多有不足,敬請批評指正!