您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)如何解決c++野指針的問(wèn)題的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。
1.定義
指向非法的內(nèi)存地址指針叫作野指針(Wild Pointer),也叫懸掛指針(Dangling Pointer),意為無(wú)法正常使用的指針。
2.出現(xiàn)野指針的常見(jiàn)情形
2.1使用未初始化的指針
出現(xiàn)野指針最典型的情形就是在定義指針變量之后沒(méi)有對(duì)它進(jìn)行初始化,如下面的程序。
#include <iostream> using namespace std; int main() { int* p; cout<<*p<<endl; //編譯通過(guò),運(yùn)行時(shí)出錯(cuò) }
2.2指針?biāo)傅膶?duì)象已經(jīng)消亡
指針指向某個(gè)對(duì)象之后,當(dāng)這個(gè)對(duì)象的生命周期已經(jīng)結(jié)束,對(duì)象已經(jīng)消亡后,仍使用指針訪問(wèn)該對(duì)象,將出現(xiàn)運(yùn)行時(shí)錯(cuò)誤。考察如下程序。
#include <iostream> using namespace std; int* retAddr() { int num=10; return # } int main() { int* p=NULL; p=retAddr(); cout<<&p<<endl; cout<<*p<<endl; }
以上程序編譯和運(yùn)行都沒(méi)有錯(cuò)誤,輸出結(jié)果如下:
001AFD48
1701495776
最后一行,輸出的并非想象中的num的值10,因?yàn)樽兞縩um是存儲(chǔ)在??臻g的局部變量,離開(kāi)函數(shù)超出其作用域后就會(huì)被釋放掉,因此輸出的值就是不確定的值了。
注意:
(1)如果將cout<<&p<< endl
;注釋掉,可以正常輸出num的值為10,或者將cout<<*p<<endl
;放在前面,也能正常輸出,原因是局部變量num的內(nèi)存空間雖然在函數(shù)retAddr()調(diào)用結(jié)束后被回收,但是其值還沒(méi)有被修改,語(yǔ)句cout<<&p<<endl
;實(shí)際上是調(diào)用cout對(duì)象的成員函數(shù)ostream& operator<<()
,重新使用了retAddr()調(diào)用時(shí)使用的棧空間,此時(shí)num的內(nèi)存空間被改寫(xiě),輸出了不確定值。
(2)修改p指向的內(nèi)存空間的值,可以正常編譯運(yùn)行。
int main() { int* p = NULL; p = retAddr(); *p = 11; cout << *p << endl; }
上面的代碼輸出11。這里p指向的地址空間雖然不屬于main函數(shù)的??臻g,但是操作系統(tǒng)在程序運(yùn)行時(shí)會(huì)預(yù)先開(kāi)辟一段可用的??臻g,供用戶程序使用。一般情況下,Windows默認(rèn)為1M,Linux默認(rèn)為10M,預(yù)先開(kāi)辟的??臻g并不是系統(tǒng)保護(hù)性地址,可以由程序任意改寫(xiě)并訪問(wèn),所以可以更改p指向的內(nèi)存空間的值并訪問(wèn)輸出。
2.3指針釋放后之后未置空
指針p被free或者delete之后,沒(méi)有置為NULL,讓人誤以為p是個(gè)合法的指針。對(duì)指針進(jìn)行free和delete,只是把指針?biāo)傅膬?nèi)存空間給釋放掉,但并沒(méi)有把指針本身置空,此時(shí)指針指向的就是“垃圾”內(nèi)存。釋放后的指針應(yīng)立即將指針置為NULL,防止產(chǎn)生野指針。考察如下程序。
#include <iostream> using namespace std; int main() { int* p=NULL; p=new int[10]; delete p; cout<<"p[0]:"<<p[0]<<endl; }
程序輸出結(jié)果是一個(gè)隨機(jī)值,因?yàn)榇藭r(shí)的指針?biāo)赶虻目臻g是垃圾內(nèi)存,存放著隨機(jī)值。
3.如何避免野指針的出現(xiàn)
野指針有時(shí)比較隱蔽,編譯器不能發(fā)現(xiàn),為了防止野指針帶來(lái)的危害,開(kāi)發(fā)人員應(yīng)該注意以下幾點(diǎn)。
(1)C++引入了引用機(jī)制,如果使用引用可以達(dá)到編程目的,就可以不必使用指針。因?yàn)橐迷诙x的時(shí)候,必須初始化,所以可以避免野指針的出現(xiàn)。
(2)如果一定要使用指針,那么需要在定義指針變量的同時(shí)對(duì)它進(jìn)行初始化操作。定義時(shí)將其置位NULL或者指向一個(gè)有名變量。
(3)對(duì)指針進(jìn)行free或者delete操作后,將其設(shè)置為NULL。對(duì)于使用 free 的情況,常常定義一個(gè)宏或者函數(shù) xfree 來(lái)代替 free 置空指針:
#define xfree(x) free(x); x = NULL;
感謝各位的閱讀!關(guān)于如何解決c++野指針的問(wèn)題就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。