C語(yǔ)言難點(diǎn)揭秘[4]

字號(hào):

使這些格式元素成為您日常工作的一部分??梢允褂酶鞣N方法解決內(nèi)存問(wèn)題:
    專用庫(kù)
    語(yǔ)言
    軟件工具
    硬件檢查器
    在這整個(gè)領(lǐng)域中,我始終認(rèn)為最有用并且投資回報(bào)率的是考慮改進(jìn)源代碼的風(fēng)格。它不需要昂貴的代價(jià)或嚴(yán)格的形式;可以始終取消與內(nèi)存無(wú)關(guān)的段的注釋,但影響內(nèi)存的定義當(dāng)然需要顯式注釋。添加幾個(gè)簡(jiǎn)單的單詞可使內(nèi)存結(jié)果更清楚,并且內(nèi)存編程會(huì)得到改進(jìn)。
    我沒(méi)有做受控實(shí)驗(yàn)來(lái)驗(yàn)證此風(fēng)格的效果。如果您的經(jīng)歷與我一樣,您將發(fā)現(xiàn)沒(méi)有說(shuō)明資源影響的策略簡(jiǎn)直無(wú)法忍受。這樣做很簡(jiǎn)單,但帶來(lái)的好處太多了。
    檢測(cè)
    檢測(cè)是編碼標(biāo)準(zhǔn)的補(bǔ)充。二者各有裨益,但結(jié)合使用效果特別好。機(jī)靈的 C 或 C++ 專業(yè)人員甚至可以瀏覽不熟悉的源代碼,并以極低的成本檢測(cè)內(nèi)存問(wèn)題。通過(guò)少量的實(shí)踐和適當(dāng)?shù)奈谋舅阉?,您能夠快速?yàn)證平衡的 *alloc() 和 free() 或者 new 和 delete 的源主體。人工查看此類內(nèi)容通常會(huì)出現(xiàn)像清單 7 中一樣的問(wèn)題。
    清單 7. 棘手的內(nèi)存泄漏
     static char *important_pointer = NULL;
     void f9()
     {
     if (!important_pointer)
     important_pointer = malloc(IMPORTANT_SIZE);
     ...
     if (condition)
     /* Ooops! We just lost the reference
     important_pointer already held. */
     important_pointer = malloc(DIFFERENT_SIZE);
     ...
     }
    如果 condition 為真,簡(jiǎn)單使用自動(dòng)運(yùn)行時(shí)工具不能檢測(cè)發(fā)生的內(nèi)存泄漏。仔細(xì)進(jìn)行源分析可以從此類條件推理出證實(shí)正確的結(jié)論。我重復(fù)一下我寫的關(guān)于風(fēng)格的內(nèi)容:盡管大量發(fā)布的內(nèi)存問(wèn)題描述都強(qiáng)調(diào)工具和語(yǔ)言,對(duì)于我來(lái)說(shuō),的收獲來(lái)自“軟的”以開發(fā)人員為中心的流程變更。您在風(fēng)格和檢測(cè)上所做的任何改進(jìn)都可以幫助您理解由自動(dòng)化工具產(chǎn)生的診斷。
    靜態(tài)的自動(dòng)語(yǔ)法分析
    當(dāng)然,并不是只有人類才能讀取源代碼。您還應(yīng)使靜態(tài)語(yǔ)法分析 成為開發(fā)流程的一部分。靜態(tài)語(yǔ)法分析是 lint、嚴(yán)格編譯 和幾種商業(yè)產(chǎn)品執(zhí)行的內(nèi)容:掃描編譯器接受的源文本和目標(biāo)項(xiàng),但這可能是錯(cuò)誤的癥狀。
    希望讓您的代碼無(wú) lint。盡管 lint 已過(guò)時(shí),并有一定的局限性,但是,沒(méi)有使用它(或其較高級(jí)的后代)的許多程序員犯了很大的錯(cuò)誤。通常情況下,您能夠編寫忽略 lint 的優(yōu)秀的專業(yè)質(zhì)量代碼,但努力這樣做的結(jié)果通常會(huì)發(fā)生重大錯(cuò)誤。其中一些錯(cuò)誤影響內(nèi)存的正確性。與讓客戶首先發(fā)現(xiàn)內(nèi)存錯(cuò)誤的代價(jià)相比,即使對(duì)這種類別的產(chǎn)品支付最昂貴的許可費(fèi)也失去了意義。清除源代碼?,F(xiàn)在,即使 lint 標(biāo)記的編碼可能向您提供所需的功能,但很可能存在更簡(jiǎn)單的方法,該方法可滿足 lint,并且比較強(qiáng)鍵又可移植。