程式中通常包含著靜態記憶體和棧記憶體。靜態記憶體用來儲存區域性static物件、類static資料成員以及定義在任何函式之外的變數(全域性變數)。棧記憶體用來儲存定義在函式內的非static物件。分配在靜態或棧記憶體中的物件由編譯器自動建立和銷毀。對於棧物件,僅在定義的程式塊執行時才存在,程式退出,棧物件也隨即銷毀;static物件和全域性物件則是在程式結束時銷毀。除了靜態記憶體和棧記憶體,程式還擁有一塊記憶體池,這部分也就是稱為堆。在使用堆空間是就需要使用動態記憶體分配。
記憶體洩漏:是指程式中己動態分配的堆記憶體由於某種原因程式未釋放或無法釋放,造成系統記憶體的浪費,導致程式執行速度減慢甚至系統崩潰等嚴重後果。
對於伺服器程式及需要長時間執行的程式來說,檢測和解決記憶體洩漏是程式設計師必備的技能。
1. 記憶體洩漏出現的情況總結
首先總結一下c++在語法上的錯誤使用導致的記憶體洩漏,所以在編寫程式時,就盡量避免錯誤的編寫。
(1) 正確的使用new和delete函式,需要注意的是new和delete要匹配使用,對於初學者這種情況是最常出現的。一般出錯的地方像如下的例子,在指標p的值被另乙個函式所使用。
[cpp]
view plain
copy
char
* funa()
void
funerrorb()
[cpp]
view plain
copy
(2) 釋放物件陣列時,沒有使用delete。如例子所示:
[cpp]
view plain
copy
void funerrora()
(3) 雙指標釋放錯誤,存在指標釋放的遺漏。如例子正確的釋放乙個雙指標
[cpp]
view plain
copy
void funrighta()
if(p!=nullptr)
delete p;
p = nullptr;
} }
(4)缺少拷貝建構函式。在類裡存在成員變數是指標時,在進行賦值=運算和按值傳參時,必須過載拷貝建構函式,重新實現其指標拷貝的部分.
(5)沒有將基類的析構函式定義為虛函式。當基類指標指向子類物件時,如果基類的析構函式不是virtual,那麼子類的析構函式將不會被呼叫,子類的資源沒有正確是釋放,因此造成記憶體洩露。
(6)呼叫庫存在記憶體洩漏。在使用由個人包裝或者未完全測試的庫時,要確定此庫對本程式不存在效能的影響。
常見的記憶體洩漏
vector v new vector 10 for int i 1 i 100 i 如果我們僅僅釋放引用本身,那麼 vector 仍然引用該物件,所以這個物件對 gc 來說是不可 的。因此,如果物件加入到vector 後,還必須從 vector 中刪除,最簡單的方法就是將 vector 物件設定為...
C 記憶體洩漏
記憶體洩漏 記憶體溢位 out of memory 通俗理解就是記憶體不夠,通常在執行大型軟體或遊戲時,軟體或遊戲所需要的記憶體遠遠超出了你主機內安裝的記憶體所承受大小,就叫記憶體溢位。記憶體洩漏 memory leak 是指程式中已動態分配的堆記憶體由於某種原因程式未釋放或無法釋放,造成系統記憶體...
Android記憶體洩漏常見情況
android記憶體中的洩漏主要是由堆記憶體造成的。2 靜態類強引用了某個activity導致activity無法被 3 非靜態內部類的使用,非靜態內部類和匿名內部類都會隱式的持有其外部類的引用。建議使用靜態內部類加弱應用的方式。4 對於使用了braodcastreceiver,contentobs...