怎麼有效的防止記憶體洩漏

2021-06-28 22:14:48 字數 4015 閱讀 3249

1.盡量不去手動分配記憶體。比如,我一般不使用陣列,而使用stl的vector.
2.如果需要手動分配陣列,盡量使用stl中的分配方式,或者使用stl和boost中的智慧型指標。
2. 對於c和c++這種沒有garbage collection 的語言來講,我們主要關注兩種型別的記憶體洩漏:

堆記憶體洩漏(heap leak)。對記憶體指的是程式執行中根據需要分配通過malloc,realloc new等從堆中分配的一塊記憶體,再是完成後必須通過呼叫對應的 free或者delete 刪掉。如果程式的設計的錯誤導致這部分記憶體沒有被釋放,那麼此後這塊記憶體將不會被使用,就會產生heap leak. 

系統資源洩露(resource leak).主要指程式使用系統分配的資源比如 bitmap,handle ,socket等沒有使用相應的函式釋放掉,導致系統資源的浪費,嚴重可導致系統效能降低,系統執行不穩定。

首先說說標題可能取得有些大,但是可以理解為程式設計過程中有效的防止寫的**中有記憶體洩漏。好了廢話不多說了,首先看下面一段**。

[cpp]view plain

copy

class

image  

class

voice  

class

people  

;  people::people( const

std::string& n,

const

int& a,

const

int& h,

const

std::stirng& imgfilename,

const

std::string& vfilename )  

:name(n),age(a),height(h),pimg(0),pvoi(0)  

if(vfilename != 

" ")  

}  people::~people( )    

上面**粗略看似沒有問題,但是有沒有想到如果people建構函式出錯(記憶體不足,無法分配記憶體)怎麼辦?其結果可以預見,就是乙個異常丟擲來。但是我們仔細想想此時如果已經構造了image類物件,而在構造voice類物件時丟擲的錯誤,這個情況會怎麼辦?程式會因為異常而停止,後面**不會執行,那麼pimg指標所指向的記憶體就不會得到正確的釋放,那麼記憶體就洩漏了。情況如下面**:

[cpp]view plain

copy

...  

people *p =null;  

try  

delete

p;  

}  

仔細想想 new people("test",20,170,".../images/image01.jpg","../voices/voice01.dat")裡,如果最後為image分配的記憶體被丟失,因為new操作沒有成功完成,程式不會p進行賦值操作。所以catch中是沒有任何操作的,已被分配的記憶體就丟失了。

因為物件在構造中丟擲異常後c++不負責清除物件,所以我們需要重新設計建構函式讓它們在運到異常的時候自己能清除所占用的記憶體。

[cpp]view plain

copy

people::people( 

const

std::string& n,

const

int& a,

const

int& h,

const

std::stirng& imgfilename,

const

std::string& vfilename )  

:name(n),age(a),height(h),pimg(0),pvoi(0)  

if(vfilename != 

" ")  

}  catch

( ...)   

這樣就行了,解決上面的情況。讓成員變數成為const指標,這樣設計也合理,避免指標無意被改變。

[cpp]view plain

copy

image * 

const

pimg;          

//影象

voice   * const

pvoi;        

//聲音

那麼這樣就只能用成員初始化列表為指標初始化,就沒有其他地方可以給const指標賦值了。

[cpp]view plain

copy

people::people( 

const

std::string& n,

const

int& a,

const

int& h,

const

std::stirng& imgfilename,

const

std::string& vfilename )  

:name(n),age(a),height(h),  

pimg( imgfilename !=""

? new

image( imgfilename ) : 0 ),  

pvoi( vfilename != ""

? new

voice( vfilename ) : 0)  

{}  

如果這樣就重新回到上面所遇到的問題,即構造過程中丟擲異常,指標可能無法正確的釋放所佔記憶體。那麼我們可以進一步對**進行改進,如下:

[cpp]view plain

copy

people::people( 

const

std::string& n,

const

int& a,

const

int& h,

const

std::stirng& imgfilename,

const

std::string& vfilename )  

:name(n),age(a),height(h),  

pimg( initimage( imgfilename ) ),  

pvoi(  initvoice( vfilename ) )  

{}  

image* people::initimage(const

string& imgfilename)   

voice* people::initvoice(const

string& vfilename)  

catch

(... )  

}  這樣在呼叫構建voice物件中加入try...catch...用於釋放pimg所占用的記憶體空間。其實有乙個比其更簡單的方法就是使用智慧型指標。

[cpp]view plain

copy

const

auto_ptrpimg;  

const

auto_ptrpvoi;  

people::people( const

std::string& n,

const

int& a,

const

int& h,

const

std::stirng& imgfilename,

const

std::string& vfilename )  

:name(n),age(a),height(h),  

pimg( imgfilename !=""

? new

image( imgfilename ) : 0 ),  

pvoi( vfilename != ""

? new

voice( vfilename ) : 0)  

{}  

那麼問題就算解決了,因為當其中有乙個建立失敗,離開函式的時候,智慧型指標會自動刪除已經建立的空間,防止記憶體洩漏了。

防止handler記憶體洩漏

記憶體洩漏 程式執行會用到記憶體,在退出程式的時候,占用記憶體的資料沒有釋放,那麼當資料越來越多的時候,就會產生記憶體洩漏。handler為什麼會記憶體洩漏呢,handler是個內部類,內部類會持有外部類的引用,內部類需要依賴外部類。handler需要定義為靜態類,當你推出activity,hand...

try finally 妙用,防止記憶體洩漏

function createbutton obj.nm use ver function return obj 這裡由於需要返回建立的物件,所以不能把obj直接設為null.return 後obj是區域性變數,不能在外部斷開其與htmlelement的引用.ie中將出現問題洩漏問題 按鈕.做某些事...

React 防止記憶體洩漏處理

在元件上進行axios的非同步請求,請求之後setstate儲存資料 然後在元件之間快速切換元件 然後就會出現這個報錯了,報這個錯主要是因為,不能在元件銷毀後設定state,防止出現記憶體洩漏的情況!1.比較簡單粗暴的處理方法是,直接設定componentwillunmount componentw...