在symbian os中,有3中方法來處理記憶體洩露:捕獲裝置trap和trapd;清理棧(cleanupstack)和二階構造。
一.trap和trapd
trap和trapd是兩個預定義的巨集,作用是捕獲函式所產生的異常。
程式:
1void
createobjectl()25
tint err;
6trap(err, createobjectl());
在symbian os中,如果乙個函式產生異常,系統會立即返回到它的上一級呼叫函式中。因此,如果函式createobjectl()函式中產生異常,這一異常將會被trap語句中所捕獲。
trap需要兩個引數,第乙個tint型別的引數,用於儲存異常**,如果沒有出現異常,則err值為0或者kerrnone;如果有異常,則err將為乙個代表一類異常的負數。第二個引數為呼叫函式,一旦呼叫函式出現異常,它將立刻返回到trad中,出現異常語句後的所有**將不再執行。
trapd和trap兩者僅僅有一點區別,在呼叫trapd前不需要定義err變數。
trap和trapd在捕獲到異常之後,程式設計師需要對這一異常進行處理,例如使用__assert_always(!error, user::panic(ktxtepoc32ex,error).
二.清理棧cleanupstack
清理棧用於防止函式產生異常時的記憶體洩露
下面通過一段**來說明為什麼需要使用清理棧
voiddoexamplel()
這段**中,首先在堆中new乙個cexample*物件myexample,然後對myexample成員變數進行賦值,並且呼叫成員函式dosomethingsl(),呼叫完成後,刪除物件所指的堆空間。看起來似乎完美,但是仔細分析就會發現,dosomethingsl()函式呼叫會發生異常,如果函式呼叫時,發生異常,函式會立即異常退出。在函式退出之前,它會釋放函式中所有的引數和區域性變數,也就是說物件myexample被釋放掉,但是它所指向的空間卻來不及釋放,這樣就產生了記憶體洩露。也許有人會問,不是有delete的麼?但是函式在呼叫dosomethingsl()處異常退出,後面的delete語句沒有機會執行,也就沒有辦法釋放相應的堆空間,從而造成上面所描述的記憶體洩露。
在symbian os中,通過cleanupstack來處理這類記憶體洩露
修改後的程式如下
1void
doexamplel()
2
這裡在呼叫dosomethingsl()之前,將物件myexample壓入清理棧,從而確保程式在執行期間,出現異常也不會產生記憶體洩露。
注意:類的成員不需要壓入清理棧中,因為釋放成員的空間是由類的析構函式來完成,如果將其壓入清理棧,出棧時,會造成兩次刪除,從而出現兩次刪除異常。
三.二階構造
二階構造是為了防止在構造物件是產生記憶體洩露。
二階建構函式的基本思想是將可能產生異常的**包含在二階建構函式中,將不會產生異常的**放在普通建構函式中。
通過下面的**來說明為什麼需要使用二階構造。
1class
cfulltime : cbase214
15cfulltime::cfulltime(tint ahour, tint aminute, tint asecond)
1622
23cfulltime::
~cfulltime()
24
主函式**如下
分析:它將在堆區域上分配乙個cfulltime的例項物件,並將位址賦給cf指標,然後呼叫類的建構函式來初始化這個物件。考慮這樣乙個問題,如果建構函式出現異常,那麼就會導致沒有指標指向成功分配給cfulltime型別物件的區域,那麼這塊記憶體就成了孤立記憶體,無法被釋放,這將導致記憶體洩漏。
二階構造,顧名思義,就是將構造分為二個階段:
第一階段:普通構造,沒有包含可能導致異常退出的**;
第二階段:包含可能導致異常退出的**。
改造後的程式**如下:
class
cfulltime : cbase
cfulltime::cfulltime(tint ahour, tint aminute, tint asecond)
cfulltime
*cfulltime::newl(tint ahour, tint aminute, tint asecond)
cfulltime
*cfulltime::newlc(tint ahour, tint aminute, tint asecond)
void
cfulltime::construct()
cfulltime::
~cfulltime()
在這裡,遇到幾點疑問:
1.在生成這個物件指標的時候,到底是用newl呢還是用newlc呢?
答:如果物件的例項是作為類成員的,那麼用newl,如果是區域性變數,那麼用newlc,用完後popanddestory
2.newlc方法pushl了乙個物件,卻為什麼沒有pop出來?
答:newlc中用pushl,就是為了呼叫constructl方法。在constructl中使用this指標即可呼叫該物件的其他方法。pushl之後沒有pop配對,是為了讓外界(例項化該物件的其他物件)繼續呼叫該物件的其他l方法,外界使用完該物件後popanddestory之。
3.如果用newlc的話,在物件銷毀的時候是否用該手動pop一下?
答:是的。如果你直接呼叫newlc函式,最後銷毀物件的時候肯定要pop一下。
學習SYMBIAN,也再複習下記憶體管理的知識。
發生記憶體錯誤是件非常麻煩的事情.編譯器不能自動發現這些錯誤,通常是在程式執行時才能捕捉到.而這些錯誤大多沒有明顯的症狀,時隱時現,增加了改錯的難度。象個定時炸彈似的。下邊我列舉下程式中記憶體常見的錯誤 記憶體申請沒有成功,但你你由於不知道卻使用了它。記憶體分配雖然成功,但並沒有初始化。記憶體分配成...
objective C程式 記憶體管理
記憶體管理 記憶體管理概念 由於移動裝置的記憶體機器有限所以每個被占用的記憶體也是有限的。不用的記憶體是需要 的,否則程式會崩潰 oc 管理記憶體的範圍 管理任何繼承nsobject的物件,對其他的基本資料型別無效 基本資料型別資料占用的儲存空間是固定的 一般儲存在棧區。物件型別是程式執行過程中動態...
移植程式到symbian平台
symbian平台理論上可以平移標準的c c 語 言程式,以及標準庫。只需要在mmp檔案中進行如下編寫 target hello.exe targettype exe uid 0 sourcepath source slhello.c systeminclude epoc32 include lib...