C程序中可怕的野指針圖文詳解
一、疑問(wèn)點(diǎn)
指針是C語(yǔ)言一個(gè)很強(qiáng)大的功能,同時(shí)也是很容易讓人犯錯(cuò)的一個(gè)功能,用錯(cuò)了指針,輕者只是報(bào)個(gè)錯(cuò),重者可能整個(gè)系統(tǒng)都崩潰了。下面是大家在編寫(xiě)C程序時(shí),經(jīng)常遇到的一種錯(cuò)誤的使用方法,也許在你的學(xué)習(xí)和工作中就是這樣用的,很危險(xiǎn)。
實(shí)例程序如圖1所示:
圖1 實(shí)例程序
這段程序比較簡(jiǎn)單,str1指向的內(nèi)存區(qū)域存放了一個(gè)字符串“123”,把“123”賦值到str2指向的內(nèi)存區(qū)域,編譯時(shí)會(huì)給出一個(gè)告警:
local variable 'str2' used without having been initialized
意思是說(shuō),“str2”這個(gè)變量沒(méi)有初始化。我們可以不理會(huì)這個(gè)告警,并且繼續(xù)運(yùn)行程
序,但是“str2”在定義時(shí)沒(méi)有給初值,是一個(gè)野指針,程序運(yùn)行的結(jié)果可能是非??膳碌?。下面我們來(lái)詳細(xì)分析下,野指針的可怕之處。
二、可怕的野指針
我們程序中的
strcpy(str2 , str1); printf("str2指向的字符串是 %s",str2);
這兩行代碼注釋掉,然后運(yùn)行程序,看看str2輸出的值是多少。
運(yùn)行結(jié)果如下:
可見(jiàn)str2被系統(tǒng)賦予一個(gè)值3435973836,3435973836是一個(gè)內(nèi)存的地址,也就是指針str2指向這段內(nèi)存,這段內(nèi)存上保存的數(shù)據(jù)可能是其他某個(gè)程序的數(shù)據(jù),例如保存著“hello world!”,如圖2所示,也可能什么數(shù)據(jù)也沒(méi)有。
圖2 其他程序的重要數(shù)據(jù)
如果這段內(nèi)存保存著其他程序的重要數(shù)據(jù),通過(guò)strcopy函數(shù)將“123”復(fù)制給了這段內(nèi)存,也就是修改了這個(gè)重要數(shù)據(jù),這段內(nèi)存保存的數(shù)據(jù)變成了“123lo world!”,如圖3所示,那么其他程序可能就崩掉了!
圖3 其他程序的重要數(shù)據(jù)被改寫(xiě)
三、避免野指針的方法
為了防止野指針帶來(lái)的災(zāi)難,建議指針在定義時(shí)給一個(gè)初值,比如“NULL”,意思是不指向任何內(nèi)存地址。然后再使用malloc函數(shù)給指針?lè)峙湟粔K存儲(chǔ)空間。修改的程序如圖4所示:
圖4 避免野指針的改法程序
在定義str2時(shí)賦予初值“NULL”,這樣str2就不會(huì)指向任何內(nèi)存。再通過(guò)malloc函數(shù),申請(qǐng)一段空的內(nèi)存區(qū)域,也就是沒(méi)有任何程序使用的內(nèi)存區(qū)域,讓str2指向這段空的內(nèi)存區(qū)域,如圖5所示,此時(shí)再把“123”賦值到這段空的內(nèi)存區(qū)域,這樣就安全了。程序的最后,再主動(dòng)釋放掉這段內(nèi)存區(qū)域,讓str2再次不指向任何區(qū)域。
圖5 系統(tǒng)分配的內(nèi)存區(qū)域
運(yùn)行結(jié)果如圖6所示:
圖6 運(yùn)行結(jié)果
由結(jié)果可見(jiàn),系統(tǒng)分配的沒(méi)有任何其他程序使用的內(nèi)存地址是“2428680”。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
講解C語(yǔ)言編程中指針賦值的入門(mén)實(shí)例
這篇文章主要介紹了講解C語(yǔ)言編程中指針賦值的入門(mén)實(shí)例,通過(guò)const int i與int *const pi這樣兩個(gè)例子來(lái)分析指針的賦值和地址指向,需要的朋友可以參考下2015-12-12C++ 實(shí)現(xiàn)高性能HTTP客戶(hù)端
HttpClient可以實(shí)現(xiàn)所有HTTP的方法,通過(guò)API傳輸接收HTTP消息。本文詳細(xì)講解了HttpClient,以及如何運(yùn)用C++實(shí)現(xiàn)HTTP客戶(hù)端,感興趣的朋友可以參考一下2021-08-08C語(yǔ)言如何實(shí)現(xiàn)BOOL類(lèi)型
這篇文章主要介紹了C語(yǔ)言如何實(shí)現(xiàn)BOOL類(lèi)型問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02C語(yǔ)言中字符型數(shù)據(jù)和浮點(diǎn)型數(shù)據(jù)介紹
大家好,本篇文章主要講的是C語(yǔ)言中字符型數(shù)據(jù)和浮點(diǎn)型數(shù)據(jù)介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下,方便下次瀏覽2022-01-01詳解C語(yǔ)言在STM32中的內(nèi)存分配問(wèn)題
這篇文章主要介紹了C語(yǔ)言在STM32中的內(nèi)存分配,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12C++解決大數(shù)組棧內(nèi)存不夠問(wèn)題的方法分析
這篇文章主要介紹了C++解決大數(shù)組棧內(nèi)存不夠問(wèn)題的方法,結(jié)合實(shí)例形式對(duì)比分析了C++針對(duì)大數(shù)組棧內(nèi)存不足情況的常見(jiàn)解決方法及其優(yōu)缺點(diǎn),具有一定參考借鑒價(jià)值,需要的朋友可以參考下2018-05-05C++中用substr()函數(shù)消除前后空格的解決方法詳解
本篇文章是對(duì)C++中用substr()函數(shù)消除前后空格的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05