★ 問(wèn)題現(xiàn)象:在析構(gòu)函數(shù)中釋放引用的 COM 指針,導(dǎo)致異常。
1、總是在一個(gè)固定地址報(bào)告異常。該地址的匯編碼在程序退出前可見(jiàn)(有效),在異常出現(xiàn)時(shí)不可見(jiàn)(全為問(wèn)號(hào))。
2、設(shè)置斷點(diǎn)后發(fā)現(xiàn),調(diào)試器無(wú)法計(jì)算該指針表達(dá)式的值;
3、在內(nèi)存窗口中查看該指針指向的內(nèi)容,發(fā)現(xiàn)可視范圍內(nèi)全是問(wèn)號(hào)(不可訪問(wèn))
★ 原因、查找過(guò)程
1、在欲釋放的指針?biāo)诘膁ll卸載的地方(CXxxxApp::ExitInstance())設(shè)上斷點(diǎn),發(fā)現(xiàn)它在出錯(cuò)代碼前就執(zhí)行了!
2、因?yàn)槌鲥e(cuò)代碼處也是一個(gè)dll模塊內(nèi),而且和出錯(cuò)指針對(duì)象所在的dll不是一個(gè)。據(jù)此,判斷應(yīng)該是,主模塊(exe)在卸載dll時(shí),先卸載了指針?biāo)诘膁ll(而且報(bào)了內(nèi)存泄露),再卸載出錯(cuò)代碼所在的dll,由于此時(shí)指針?biāo)诘哪K已經(jīng)釋放,故內(nèi)存失效!
★ 解決辦法
1、對(duì)于dll模塊的代碼,絕對(duì)不要在析構(gòu)函數(shù)或模塊退出時(shí)訪問(wèn)另一個(gè)dll的內(nèi)容!因?yàn)?dll 的卸載順序是不可靠或很難管理的!(exe卸載的順序是可靠的,exe必定是最后卸載)
2、如果要在結(jié)束時(shí)釋放某些東西,應(yīng)該為 dll 導(dǎo)出一個(gè)類似‘Uninitialize()’的函數(shù),由主模塊(exe)主動(dòng)調(diào)用!