資源管理 防止資源洩漏

2021-05-28 09:34:45 字數 2915 閱讀 3012

在傳統的資源管理中,我們常用的技術是:在建構函式中申請資源,在析構函式中釋放資源。但是這有個缺點,就是當在建構函式中申請資源時,如果發生資源申請異常,就會導致建構函式失敗;這樣一來,當構造的物件離開作用域時,析構函式不會呼叫,原因是:如果建構函式不能正常完成時,析構函式就不會做相應的呼叫。這樣一來,就會發生資源洩漏——申請了的資源無法收回。

在構造物件時,我知道一定要在建構函式中完成,但又會有資源洩漏的危機,這就需要一些技術來防止資源洩漏。

方案一:傳統上,在建構函式中簡單地申請資源,在析構函式釋放資源。

class bookentry

if(audioclipfilename != "")

}/*上個建構函式的簡寫,如下:

bookentry(const string& name, const string& address="",

const string& imagefilename="", const string& audioclipfilename="")

:thename(name), theaddress(address),

theimage(imagefilename != "" ? new image(imagefilename) : 0),

theaudioclip(audioclipfilename != "" ? new audioclip(audioclipfilename) : 0)

*/~bookentry()

void addphonenumber(const phonenumber& number);

.......

private:

string thename;

string theaddress;

listthephones;

image *theimage;

audioclip *theaudioclip;

};以上是常規的資源申請與釋放,但是有時它並不一定能正常工作。

分析:如果在申請第乙個資源——theimage=new image(imagefilename);——成功,但在申請第二個資源—— theaudioclip=new audioclip(audioclipfilename)——失敗時,這就會導致建構函式失敗,所以建構函式就不會做出正常的呼叫(我們也沒辦法完成這種情況下的析構函式的呼叫),這樣一為,就會導致資源洩漏——申請的第乙個資源無法釋放。因此,這種方法並不是很完美!我們需要另外一種方法。

方案二:在建構函式中申請資源時,把每乙個資源申請放在乙個函式中,然後再捕捉是否有任何異常發生,如果有任何異常發生,就要釋放以前所有申請過的資源。

class bookentry

~bookentry()

void addphonenumber(const phonenumber& number);

.......

private:

string thename;

string theaddress;

listthephones;

image *theimage;

audioclip *theaudioclip;

initimage(const string& imagefilename)

initaudioclip(const string& audioclipfilename)

catch (...)}}

};分析:這個方案解決了方案一中遇到的問題,這可能是個完美的結局。但是,這個方案有個缺點是:概念上應該由constructor完成的動作現在卻散布於數個函式中,在概念上卻違反了construtor的作用,造成維護上的困擾。

方案三:運用智慧型指標。在構造物件申請資源時發生了異常,當該物件離開其作用域時,智慧型指標指向的資源也會自動釋放。

class bookentry

if(audioclipfilename != "")

}/*上個建構函式的簡寫,如下:

bookentry(const string& name, const string& address="",

const string& imagefilename="", const string& audioclipfilename="")

:thename(name), theaddress(address),

theimage(imagefilename != "" ? new image(imagefilename) : 0),

theaudioclip(audioclipfilename != "" ? new audioclip(audioclipfilename) : 0)

*/~bookentry()

void addphonenumber(const phonenumber& number);

.......

private:

string thename;

string theaddress;

listthephones;

const auto_ptrtheimage;

const auto_ptrtheaudioclip;

};分析:智慧型指標使用的是raii理論。

raii是「資源獲取就是初始化」的縮語(resource acquisition is initialization),是一種利用物件生命週期來控制程式資源(如記憶體、檔案控制代碼、網路連線、互斥量等等)的簡單技術。   

raii 的一般做法是這樣的:在物件構造時獲取資源,接著控制對資源的訪問使之在物件的生命週期內始終保持有效,最後在物件析構的時候釋放資源。藉此,我們實際上把管理乙份資源的責任託管給了乙個物件。這種做法有兩大好處:   

1,我們不需要顯式地釋放資源。  

2,採用這種方式,物件所需的資源在其生命期內始終保持有效 —— 我們可以說,此時這個類維護了乙個 invariant。這樣,通過該類物件使用資源時,就不必檢查資源有效性的問題,可以簡化邏輯、提高效率。

MTK資源管理

資源檔案生成的臨時檔案主要有 custmenutree out.c,這個檔案是選單臨時檔案,生成了我們的最終顯示的選單結構。如果你新增的選單沒有顯示,正常顯示的選單突然不顯示了或者顯示錯位了,或者顯示的選單與呼叫的功能不符合了,都可以從這裡查到原因。resource base table.txt這個...

MTK資源管理

使用mtk作開發,常常不可避免和資源打交道,常使用的資源有字串,字型,選單,風格,聲音等,mtk好像沒有系統的專門的資源管理工具,導 致資源管理十分凌亂而容易出問題,雖然有些牛人也開發了一些工具來管理這些資源,但由於使用不便或者其他一些原因,比如資源由大量的巨集控制,以及修改維護 的人多,還有一些其...

linux 資源管理

一 系統資源 網路資源 儲存資源,計算資源 二 系統資源管理名命令 1.檢視目錄下的檔案使用情況 du sh 目錄 檔案 注 du sh檢視的是目錄 檔案占用block塊的大小 ll h檢視檔案 目錄的本身大小 2.檢視檔案系統 格式化好的分割槽 的使用情況 df h 注 檢視檔案系統使用i節點的情...