當(dāng)前位置:首頁 > 公眾號精選 > 程序喵大人
[導(dǎo)讀]來源:IBN,作者:CameronLairdhttps://www.ibm.com/developerworks/cn/aix/library/au-memorytechniques.html本文將帶您了解一些良好的和內(nèi)存相關(guān)的編碼實(shí)踐,以將內(nèi)存錯誤保持在控制范圍內(nèi)。內(nèi)存錯誤是C...

來源:IBN,作者:Cameron Lairdhttps://www.ibm.com/developerworks/cn/aix/library/au-memorytechniques.html

本文將帶您了解一些良好的和內(nèi)存相關(guān)的編碼實(shí)踐,以將內(nèi)存錯誤保持在控制范圍內(nèi)。內(nèi)存錯誤是 C 和 C 編程的禍根:它們很普遍,認(rèn)識其嚴(yán)重性已有二十多年,但始終沒有徹底解決,它們可能嚴(yán)重影響應(yīng)用程序,并且很少有開發(fā)團(tuán)隊對其制定明確的管理計劃。但好消息是,它們并不怎么神秘。


引言



C 和 C 程序中的內(nèi)存錯誤非常有害:它們很常見,并且可能導(dǎo)致嚴(yán)重的后果。來自計算機(jī)應(yīng)急響應(yīng)小組(請參見參考資料)和供應(yīng)商的許多最嚴(yán)重的安全公告都是由簡單的內(nèi)存錯誤造成的。自從 70 年代末期以來,C 程序員就一直討論此類錯誤,但其影響在至今年仍然很大。更糟的是,如果按我的思路考慮,當(dāng)今的許多 C 和 C 程序員可能都會認(rèn)為內(nèi)存錯誤是不可控制而又神秘的頑癥,它們只能糾正,無法預(yù)防。
但事實(shí)并非如此。本文將讓您在短時間內(nèi)理解與良好內(nèi)存相關(guān)的編碼的所有本質(zhì):

正確的內(nèi)存管理的重要性



存在內(nèi)存錯誤的 C 和 C 程序會導(dǎo)致各種問題。如果它們泄漏內(nèi)存,則運(yùn)行速度會逐漸變慢,并最終停止運(yùn)行;如果覆蓋內(nèi)存,則會變得非常脆弱,很容易受到惡意用戶的攻擊。從 1988 年著名的莫里斯蠕蟲攻擊到有關(guān) Flash Player 和其他關(guān)鍵的零售級程序的最新安全警報都與緩沖區(qū)溢出有關(guān):“大多數(shù)計算機(jī)安全漏洞都是緩沖區(qū)溢出”,Rodney Bates 在 2004 年寫道。
在可以使用 C 或 C 的地方,也廣泛支持使用其他許多通用語言(如 Java?、Ruby、Haskell、C#、Perl、Smalltalk 等),每種語言都有眾多的愛好者和各自的優(yōu)點(diǎn)。但是,從計算角度來看,每種編程語言優(yōu)于 C 或 C 的主要優(yōu)點(diǎn)都與便于內(nèi)存管理密切相關(guān)。與內(nèi)存相關(guān)的編程是如此重要,而在實(shí)踐中正確應(yīng)用又是如此困難,以致于它支配著面向?qū)ο缶幊陶Z言、功能性編程語言、高級編程語言、聲明性編程語言和另外一些編程語言的所有其他變量或理論。

與少數(shù)其他類型的常見錯誤一樣,內(nèi)存錯誤還是一種隱性危害:它們很難再現(xiàn),癥狀通常不能在相應(yīng)的源代碼中找到。例如,無論何時何地發(fā)生內(nèi)存泄漏,都可能表現(xiàn)為應(yīng)用程序完全無法接受,同時內(nèi)存泄漏不是顯而易見。

因此,出于所有這些原因,需要特別關(guān)注 C 和 C 編程的內(nèi)存問題。讓我們看一看如何解決這些問題,先不談是哪種語言。

內(nèi)存錯誤的類別



首先,不要失去信心。有很多辦法可以對付內(nèi)存問題。我們先列出所有可能存在的實(shí)際問題:

1.內(nèi)存泄漏2.錯誤分配,包括大量增加 free()釋放的內(nèi)存和未初始化的引用3.懸空指針4.數(shù)組邊界違規(guī)
這是所有類型。即使遷移到 C 面向?qū)ο蟮恼Z言,這些類型也不會有明顯變化;無論數(shù)據(jù)是簡單類型還是 C 語言的 struct或 C 的類,C 和 C 中內(nèi)存管理和引用的模型在原理上都是相同的。以下內(nèi)容絕大部分是“純 C”語言,對于擴(kuò)展到 C 主要留作練習(xí)使用。

內(nèi)存泄漏
在分配資源時會發(fā)生內(nèi)存泄漏,但是它從不回收。下面是一個可能出錯的模型(請參見清單 1):

清單 1. 簡單的潛在堆內(nèi)存丟失和緩沖區(qū)覆蓋

void?f1(char?*explanation)
{
????char?p1;

????p1?=?malloc(100);
????????(void)?sprintf(p1,
???????????????????????"The?f1?error?occurred?because?of?'%s'.",
???????????????????????explanation);
????????local_log(p1);
}


您看到問題了嗎?除非 local_log()對 free()釋放的內(nèi)存具有不尋常的響應(yīng)能力,否則每次對 f1的調(diào)用都會泄漏 100 字節(jié)。在記憶棒增量分發(fā)數(shù)兆字節(jié)內(nèi)存時,一次泄漏是微不足道的,但是連續(xù)操作數(shù)小時后,即使如此小的泄漏也會削弱應(yīng)用程序。

在實(shí)際的 C 和 C 編程中,這不足以影響您對 malloc()或 new的使用,本部分開頭的句子提到了“資源”不是僅指“內(nèi)存”,因為還有類似以下內(nèi)容的示例(請參見清單 2)。FILE句柄可能與內(nèi)存塊不同,但是必須對它們給予同等關(guān)注:

清單 2. 來自資源錯誤管理的潛在堆內(nèi)存丟失?

int?getkey(char?*filename)
{
????FILE?*fp;
????int?key;

????fp?=?fopen(filename,?"r");
????fscanf(fp,?"%d",?
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉
關(guān)閉