2012軟考程序員輔導(dǎo):C++內(nèi)存泄漏的解決辦法

字號(hào):

發(fā)現(xiàn)大家對(duì)寫(xiě)庫(kù)很熱衷。不過(guò),寫(xiě)一個(gè)庫(kù),用C++最麻煩的事情,就是你new完了要記著delete。不過(guò),這么傻瓜化的操作,有沒(méi)有辦法讓電腦自動(dòng)完成呢?當(dāng)然是可以的。思路有以下三點(diǎn):
    1、Parent對(duì)象。
    每一個(gè)對(duì)象,都要有的parent,當(dāng)parent析構(gòu)時(shí),要帶動(dòng)他所有的children析構(gòu)。
    好處:
    實(shí)現(xiàn)簡(jiǎn)單,且具有邏輯性。
    比如:一個(gè)窗口,他的按鍵,就應(yīng)該是這個(gè)窗口的children,當(dāng)窗口析構(gòu)的時(shí)候,按鍵也必須析構(gòu)。
    壞處:
    不可以有復(fù)制構(gòu)造函數(shù)……
    這個(gè)也很好理解。A-->B-->C中,a是b的parent,b是c的parent,如果允許復(fù)制,B復(fù)制了個(gè)D,那C就有兩個(gè)parent,究竟怎么析構(gòu)呢?
    開(kāi)源庫(kù)的實(shí)現(xiàn):
    Qt實(shí)現(xiàn)了這種方式的內(nèi)存管理,尤其是對(duì)GUI框架,十分適用。
    2、引用計(jì)數(shù)的SharedPtr
    指針,進(jìn)行復(fù)制操作的時(shí)候,引用計(jì)數(shù)+1,析構(gòu)的時(shí)候引用計(jì)數(shù)-1,當(dāng)引用計(jì)數(shù)為0的時(shí)候,釋放空間。
    好處:
    實(shí)現(xiàn)簡(jiǎn)單
    壞處:
    具有循環(huán)引用的情況。要引入WeakPtr
    開(kāi)源庫(kù)的實(shí)現(xiàn):
    Qt同時(shí)實(shí)現(xiàn)了這種技術(shù),Boost也有相關(guān)實(shí)現(xiàn)。
    我因?yàn)樽罱胱约簩?shí)現(xiàn)一套Signalandslot庫(kù),也實(shí)現(xiàn)了SharedPtr,開(kāi)源。
    地址:http://gitorious.org/raylib/raylib/blobs/master/SmartPtr.hpp
    評(píng)述:
    這是C++中最通用的實(shí)現(xiàn)手段,如果你要做一套類(lèi)庫(kù),嘗試使用SharedPtr,會(huì)讓事情變得更加簡(jiǎn)單。
    3、重載new,實(shí)現(xiàn)GC
    直接重載C++操作符,實(shí)現(xiàn)垃圾回收。初始化一個(gè)內(nèi)存池,當(dāng)內(nèi)存池滿(mǎn)的時(shí)候,進(jìn)行垃圾回收操作。
    好處:
    一勞永逸
    壞處:
    實(shí)現(xiàn)困難。
    占用內(nèi)存大。
    對(duì)已有的環(huán)境,不一定會(huì)有很好的支持。
    開(kāi)源庫(kù)的實(shí)現(xiàn):
    python和java都有垃圾回收的實(shí)現(xiàn),可以進(jìn)行參考。
    評(píng)述:
    內(nèi)存池也許不一定要做垃圾回收,如果是靜態(tài)的內(nèi)存池,可以加速內(nèi)存分配的過(guò)程。