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

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

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


引言



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

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



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

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

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

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



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

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

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

清單 1. 簡(jiǎn)單的潛在堆內(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);
}


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

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

清單 2. 來(lái)自資源錯(cuò)誤管理的潛在堆內(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)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉
關(guān)閉