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