如何检测C语言中的内存漏洞(leak)?
生活随笔
收集整理的這篇文章主要介紹了
如何检测C语言中的内存漏洞(leak)?
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在動態(tài)分配的內(nèi)存單元(即由函數(shù)malloc()或ealloc()分配的內(nèi)存單元)不再使用卻沒有被釋放的情況下,會出現(xiàn)內(nèi)存漏洞。未釋放內(nèi)存單元本身并不是一種錯(cuò)誤,編譯程序不會因此報(bào)告出錯(cuò),程序也不會因此而立即崩潰。但是,如果不再使用而又沒有被釋放的內(nèi)存單元越來越多,程序所能使用的內(nèi)存空間就越來越小。最終,當(dāng)程序試圖要求分配內(nèi)存時(shí),就會發(fā)現(xiàn)已經(jīng)沒有可用的內(nèi)存空間。這時(shí),尤其是當(dāng)程序員沒有考慮到內(nèi)存分配失敗的可能性時(shí),程序的運(yùn)行就會出現(xiàn)異常現(xiàn)象。
內(nèi)存漏洞是最難檢測的錯(cuò)誤之一,同時(shí)也是最危險(xiǎn)的錯(cuò)誤。導(dǎo)致這個(gè)問題的編程錯(cuò)誤很可能出現(xiàn)在程序的開始部分,但只有當(dāng)程序奠名其妙地使用完內(nèi)存后,這個(gè)問題才會暴露出來。
此時(shí)去檢查當(dāng)前那條導(dǎo)致內(nèi)存分配失敗的語句是無濟(jì)于事的,因?yàn)槟切┓峙淞藘?nèi)存卻未能按時(shí)釋放內(nèi)存的代碼可能在程序的其它地方。
遺憾的是C語言并沒有為檢測或修復(fù)內(nèi)存漏洞提供現(xiàn)成的方法。除非使用提供這種功能的商業(yè)軟件包,否則,程序員就需要以很大的耐心和精力去檢測和修復(fù)內(nèi)存漏洞。最好的辦法是在編寫程序時(shí)就充分考慮到內(nèi)存漏洞的可能性,并小心謹(jǐn)慎地處理這種可能性。
導(dǎo)致內(nèi)存漏洞的最簡單的也是最常見的原因是忘記釋放分配給臨時(shí)緩沖區(qū)的內(nèi)存空間,請看下述程序段:?
# include <stdio. h>
# include <stdlib. h>
? /*
?? *? Say hello to the user's? and put the user's name in UPPERCASE.
?? */
void SayHi( char *name )
{
????? char * UpName;
????? int a;
????? UpName = malloc(? strlen( name ) +1);
??????????????????????????? / * Allocate space for the name * /
? for( a? =0; a<strlen( name ); ++a)
????? UpName[a] = toupper( name[a]) ;
????? UpName [a] = '\0'i
????? printf("Hello, %si\n", UpName );
}
int main()
{
????? SayHi( "Dave" );
????? return( 0 );
}
這段程序中的問題是顯而易見的——它為存儲使用大寫字母的名字分配了臨時(shí)空間,但從未釋放這些空間。為了保證永遠(yuǎn)不發(fā)生類似的情況,你可以采用這樣的方法:在分配內(nèi)存的每條語句后加上相應(yīng)的free語句,然后把使用這些臨時(shí)內(nèi)存的語句插到這兩條語句之間。只要在程序中分配和釋放內(nèi)存的語句之間沒有break,continue或goto語句,這種方法就能保證每次分配的空間在使用完后就被釋放掉。
上述方法相當(dāng)繁瑣,并且不能完全避免內(nèi)存漏洞的出現(xiàn),因?yàn)樵趯?shí)際編程中,所分配的內(nèi)存空間的使用時(shí)間往往是不能預(yù)測的。此外,如果操作或刪除內(nèi)存空間的程序段有錯(cuò)誤,也會出現(xiàn)內(nèi)存漏洞。例如,在刪除鏈表的過程中,最后一個(gè)結(jié)點(diǎn)可能會丟失,或者一個(gè)指向內(nèi)存空間的指針可能會被改寫。解決這類問題的辦法只能是小心謹(jǐn)慎地編寫程序,或者象前面提到的那樣使用相應(yīng)的軟件包,或者利用語言的擴(kuò)展功能。
內(nèi)存漏洞是最難檢測的錯(cuò)誤之一,同時(shí)也是最危險(xiǎn)的錯(cuò)誤。導(dǎo)致這個(gè)問題的編程錯(cuò)誤很可能出現(xiàn)在程序的開始部分,但只有當(dāng)程序奠名其妙地使用完內(nèi)存后,這個(gè)問題才會暴露出來。
此時(shí)去檢查當(dāng)前那條導(dǎo)致內(nèi)存分配失敗的語句是無濟(jì)于事的,因?yàn)槟切┓峙淞藘?nèi)存卻未能按時(shí)釋放內(nèi)存的代碼可能在程序的其它地方。
遺憾的是C語言并沒有為檢測或修復(fù)內(nèi)存漏洞提供現(xiàn)成的方法。除非使用提供這種功能的商業(yè)軟件包,否則,程序員就需要以很大的耐心和精力去檢測和修復(fù)內(nèi)存漏洞。最好的辦法是在編寫程序時(shí)就充分考慮到內(nèi)存漏洞的可能性,并小心謹(jǐn)慎地處理這種可能性。
導(dǎo)致內(nèi)存漏洞的最簡單的也是最常見的原因是忘記釋放分配給臨時(shí)緩沖區(qū)的內(nèi)存空間,請看下述程序段:?
# include <stdio. h>
# include <stdlib. h>
? /*
?? *? Say hello to the user's? and put the user's name in UPPERCASE.
?? */
void SayHi( char *name )
{
????? char * UpName;
????? int a;
????? UpName = malloc(? strlen( name ) +1);
??????????????????????????? / * Allocate space for the name * /
? for( a? =0; a<strlen( name ); ++a)
????? UpName[a] = toupper( name[a]) ;
????? UpName [a] = '\0'i
????? printf("Hello, %si\n", UpName );
}
int main()
{
????? SayHi( "Dave" );
????? return( 0 );
}
這段程序中的問題是顯而易見的——它為存儲使用大寫字母的名字分配了臨時(shí)空間,但從未釋放這些空間。為了保證永遠(yuǎn)不發(fā)生類似的情況,你可以采用這樣的方法:在分配內(nèi)存的每條語句后加上相應(yīng)的free語句,然后把使用這些臨時(shí)內(nèi)存的語句插到這兩條語句之間。只要在程序中分配和釋放內(nèi)存的語句之間沒有break,continue或goto語句,這種方法就能保證每次分配的空間在使用完后就被釋放掉。
上述方法相當(dāng)繁瑣,并且不能完全避免內(nèi)存漏洞的出現(xiàn),因?yàn)樵趯?shí)際編程中,所分配的內(nèi)存空間的使用時(shí)間往往是不能預(yù)測的。此外,如果操作或刪除內(nèi)存空間的程序段有錯(cuò)誤,也會出現(xiàn)內(nèi)存漏洞。例如,在刪除鏈表的過程中,最后一個(gè)結(jié)點(diǎn)可能會丟失,或者一個(gè)指向內(nèi)存空間的指針可能會被改寫。解決這類問題的辦法只能是小心謹(jǐn)慎地編寫程序,或者象前面提到的那樣使用相應(yīng)的軟件包,或者利用語言的擴(kuò)展功能。
總結(jié)
以上是生活随笔為你收集整理的如何检测C语言中的内存漏洞(leak)?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 魔兽世界沙爪岩壳蟹在哪个位置刷新 沙爪岩
- 下一篇: 《悟空大乱斗》手游星球守护玩法攻略分享