最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c語言內(nèi)存泄露示例解析

 更新時間:2013年09月09日 10:09:19   作者:  
從1988年著名的莫里斯蠕蟲 攻擊到有關(guān) Flash Player 和其他關(guān)鍵的零售級程序的最新安全警報都與緩沖區(qū)溢出有關(guān):“大多數(shù)計算機安全漏洞都是緩沖區(qū)溢出”,Rodney Bates 在 2004 年寫道

正確的內(nèi)存管理的重要性
存在內(nèi)存錯誤的 C 和 C++ 程序會導致各種問題。如果它們泄漏內(nèi)存,則運行速度會逐漸變慢,并最終停止運行;如果覆蓋內(nèi)存,則會變得非常脆弱,很容易受到惡意用戶的攻擊。從 1988 年著名的莫里斯蠕蟲 攻擊到有關(guān) Flash Player 和其他關(guān)鍵的零售級程序的最新安全警報都與緩沖區(qū)溢出有關(guān):“大多數(shù)計算機安全漏洞都是緩沖區(qū)溢出”,Rodney Bates 在 2004 年寫道。

在可以使用 C 或 C++ 的地方,也廣泛支持使用其他許多通用語言(如 Java™、Ruby、Haskell、C#、Perl、Smalltalk 等),每種語言都有眾多的愛好者和各自的優(yōu)點。但是,從計算角度來看,每種編程語言優(yōu)于 C 或 C++ 的主要優(yōu)點都與便于內(nèi)存管理密切相關(guān)。與內(nèi)存相關(guān)的編程是如此重要,而在實踐中正確應用又是如此困難,以致于它支配著面向?qū)ο缶幊陶Z言、功能性編程語言、高級編程語言、聲明性編程語言和另外一些編程語言的所有其他變量或理論。

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

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

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

•內(nèi)存泄漏
•錯誤分配,包括大量增加 free() 釋放的內(nèi)存和未初始化的引用
•懸空指針
•數(shù)組邊界違規(guī)

這是所有類型。即使遷移到 C++ 面向?qū)ο蟮恼Z言,這些類型也不會有明顯變化;無論數(shù)據(jù)是簡單類型還是 C 語言的 struct 或 C++ 的類,C 和 C++ 中內(nèi)存管理和引用的模型在原理上都是相同的。以下內(nèi)容絕大部分是“純 C”語言,對于擴展到 C++ 主要留作練習使用。

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

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

復制代碼 代碼如下:

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

您看到問題了嗎?除非 local_log() 對 free() 釋放內(nèi)存具有不尋常的響應能力,否則每次對 f1 的調(diào)用都會泄漏 100 字節(jié)。在記憶棒增量分發(fā)數(shù)兆字節(jié)內(nèi)存時,一次泄漏是微不足道的,但是連續(xù)操作數(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", &key); return key; }

fopen 的語義需要補充性的 fclose。在沒有 fclose() 的情況下,C 標準不能指定發(fā)生的情況時,很可能是內(nèi)存泄漏。其他資源(如信號量、網(wǎng)絡句柄、數(shù)據(jù)庫連接等)同樣值得考慮。

內(nèi)存錯誤分配
錯誤分配的管理不是很困難。下面是一個錯誤分配示例(請參見清單 3):

清單 3. 未初始化的指針

復制代碼 代碼如下:

void f2(int datum) { int *p2; /* Uh-oh! No one has initialized p2. */ *p2 = datum; ... }

關(guān)于此類錯誤的好消息是,它們一般具有顯著結(jié)果。在 AIX® 下,對未初始化指針的分配通常會立即導致segmentation fault 錯誤。它的好處是任何此類錯誤都會被快速地檢測到;與花費數(shù)月時間才能確定且難以再現(xiàn)的錯誤相比,檢測此類錯誤的代價要小得多。

在此錯誤類型中存在多個變種。free() 釋放的內(nèi)存比 malloc() 更頻繁(請參見清單 4):

清單 4. 兩個錯誤的內(nèi)存釋放

復制代碼 代碼如下:

/* Allocate once, free twice. */ void f3() { char *p, *pp; p = malloc(10);
pp=p;
free(p); ... free(pp); } /* Allocate zero times, free once. */ void f4() { char *p;
...
/* Note that p remains uninitialized here. */ free(p); }

這些錯誤通常也不太嚴重。盡管 C 標準在這些情形中沒有定義具體行為,但典型的實現(xiàn)將忽略錯誤,或者快速而明確地對它們進行標記;總之,這些都是安全情形。

懸空指針
懸空指針比較棘手。當程序員在內(nèi)存資源釋放后使用資源時會發(fā)生懸空指針(請參見清單 5):

清單 5. 懸空指針

復制代碼 代碼如下:

void f8() { struct x *xp; xp = (struct x *) malloc(sizeof (struct x)); xp.q = 13; ... free(xp); ... /* Problem! There's no guarantee that the memory block to which xp points hasn't been overwritten. */ return xp.q; }

傳統(tǒng)的“調(diào)試”難以隔離懸空指針。由于下面兩個明顯原因,它們很難再現(xiàn):

•即使影響提前釋放內(nèi)存范圍的代碼已本地化,內(nèi)存的使用仍然可能取決于應用程序甚至(在極端情況下)不同進程中的其他執(zhí)行位置。

•懸空指針可能發(fā)生在以微妙方式使用內(nèi)存的代碼中。結(jié)果是,即使內(nèi)存在釋放后立即被覆蓋,并且新指向的值不同于預期值,也很難識別出新值是錯誤值。

懸空指針不斷威脅著 C 或 C++ 程序的運行狀態(tài)。

數(shù)組邊界違規(guī)
數(shù)組邊界違規(guī)十分危險,它是內(nèi)存錯誤管理的最后一個主要類別?;仡^看一下清單 1;如果 explanation 的長度超過 80,則會發(fā)生什么情況?回答:難以預料,但是它可能與良好情形相差甚遠。特別是,C 復制一個字符串,該字符串不適于為它分配的 100 個字符。在任何常規(guī)實現(xiàn)中,“超過的”字符會覆蓋內(nèi)存中的其他數(shù)據(jù)。內(nèi)存中數(shù)據(jù)分配的布局非常復雜并且難以再現(xiàn),所以任何癥狀都不可能追溯到源代碼級別的具體錯誤。這些錯誤通常會導致數(shù)百萬美元的損失。

.棘手的內(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); ... }
do not返回局部指針變量或者局部變量的指針,除非是一個static局部變量
char *f0() {     char temp[]="123456789"; //加上static 才是正確的
return temp; }

相關(guān)文章

  • C語言初學者代碼中的常見錯誤與問題

    C語言初學者代碼中的常見錯誤與問題

    C語言初學者犯過的很多錯誤都非常典型,在初學者中非常普遍,于是整理了一下,應該對其他初學者有借鑒意義
    2013-11-11
  • QTimer與QTime實現(xiàn)電子時鐘

    QTimer與QTime實現(xiàn)電子時鐘

    這篇文章主要為大家詳細介紹了QTimer與QTime實現(xiàn)電子時鐘,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • C++容器適配器的概念與示例

    C++容器適配器的概念與示例

    C++?STL(標準模板庫)是一套功能強大的?C++?模板類,提供了通用的模板類和函數(shù),這些模板類和函數(shù)可以實現(xiàn)多種流行和常用的算法和數(shù)據(jù)結(jié)構(gòu),如向量、鏈表、隊列、棧,今天我們來探究一下stl容器適配器的使用吧
    2023-01-01
  • C語言逆向分析語法超詳細分析

    C語言逆向分析語法超詳細分析

    這篇文章主要介紹了C語言逆向分析語法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-11-11
  • linux安裝mysql和使用c語言操作數(shù)據(jù)庫的方法 c語言連接mysql

    linux安裝mysql和使用c語言操作數(shù)據(jù)庫的方法 c語言連接mysql

    Linux下使用C語言操作數(shù)據(jù)庫的方法,我將從MySQL環(huán)境的搭建,MySQL命令的使用到使用C接口來操作MySQL等過程詳細的介紹在Linux下管理MySQL數(shù)據(jù)庫的方法
    2014-01-01
  • 深入理解atoi()與itoa()函數(shù)的用法

    深入理解atoi()與itoa()函數(shù)的用法

    本篇文章是對atoi()與itoa()函數(shù)的用法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C語言字符函數(shù)與字符串函數(shù)詳解

    C語言字符函數(shù)與字符串函數(shù)詳解

    這篇文章主要給大家介紹了關(guān)于C語言字符/字符串的相關(guān)函數(shù),文中通過示例代碼總結(jié)的非常詳細,對大家學習或者使用C語言具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2021-09-09
  • C++字符串和數(shù)字的去重操作和鞍點的尋找

    C++字符串和數(shù)字的去重操作和鞍點的尋找

    大家好,本篇文章主要講的是C++字符串和數(shù)字的去重操作和鞍點的尋找,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • QT自定義之滑動開關(guān)

    QT自定義之滑動開關(guān)

    這篇文章主要為大家詳細介紹了QT自定義之滑動開關(guān)效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • 關(guān)于C++中的static關(guān)鍵字的總結(jié)

    關(guān)于C++中的static關(guān)鍵字的總結(jié)

    C++的static有兩種用法:面向過程程序設計中的static和面向?qū)ο蟪绦蛟O計中的static。前者應用于普通變量和函數(shù),不涉及類;后者主要說明static在類中的作用
    2013-09-09

最新評論

全州县| 古丈县| 彩票| 嵊州市| 玉环县| 文成县| 澄江县| 阿荣旗| 福清市| 章丘市| 江源县| 报价| 富锦市| 垦利县| 舟山市| 石景山区| 日照市| 肇庆市| 华阴市| 府谷县| 巩留县| 山阳县| 靖安县| 昌黎县| 习水县| 仙桃市| 黑龙江省| 五家渠市| 巨野县| 芜湖市| 图木舒克市| 县级市| 唐河县| 三都| 蒙自县| 兴安盟| 潞西市| 应用必备| 内乡县| 彝良县| 武平县|