野指針

野指針

野指針指向一個已刪除的對象或未申請訪問受限記憶體區域的指針。與空指針不同,野指針無法通過簡單地判斷是否為 NULL避免,而只能通過養成良好的編程習慣來盡力減少。對野指針進行操作很容易造成程式錯誤。需對指針進行初始化,

基本介紹

  • 中文名:野指針
  • 外文名:Wild Pointer
  • 性質:指針
  • 領域:編程
成因,指針變數未初始化,指針釋放後之後未置空,指針操作超越變數作用域,規避,初始化時置 NULL,釋放時置 NULL,

成因

野指針主要是因為這些疏忽而出現的刪除或申請訪問受限記憶體區域的指針。

指針變數未初始化

任何指針變數剛被創建時不會自動成為NULL指針,它的預設值是隨機的,它會亂指一氣。所以,指針變數在創建的同時應當被初始化,要么將指針設定為NULL,要么讓它指向合法的記憶體。如果沒有初始化,編譯器會報錯“ ‘point’ may be uninitializedin the function ”。

指針釋放後之後未置空

有時指針在free或delete後未賦值 NULL,便會使人以為是合法的。別看free和delete的名字(尤其是delete),它們只是把指針所指的記憶體給釋放掉,但並沒有把指針本身幹掉。此時指針指向的就是“垃圾”記憶體。釋放後的指針應立即將指針置為NULL,防止產生“野指針”。

指針操作超越變數作用域

不要返回指向棧記憶體的指針或引用,因為棧記憶體在函式結束時會被釋放。示例程式如下:
class A {public:  void Func(void){ cout << “Func of class A” << endl; }};class B {public:  A *p;  void Test(void) {    A a;    p = &a; // 注意 的生命期 ,只在這個函式Test中,而不是整個class B  }  void Test1() {  p->Func(); // p 是“野指針”  }};
函式 Test1 在執行語句 p->Func()時,p 的值還是 a 的地址,對象 a 的內容已經被清除,所以 p 就成了“野指針” 。

規避

在養成這些習慣的情況下,野指針的危害是可以降低的:

初始化時置 NULL

指針變數一定要初始化為NULL,因為任何指針變數(除了static修飾的指針變數)剛被創建時不會自動成為NULL指針,它的預設值是隨機的。

釋放時置 NULL

當指針p指向的記憶體空間釋放時,沒有設定指針p的值為NULL。delete和free只是把記憶體空間釋放了,但是並沒有將指針p的值賦為NULL。通常判斷一個指針是否合法,都是使用if語句測試該指針是否為NULL。例如:
int *p=newint(6);delete p;// 應加入 p=NULL; 以防出錯// ...if(p != NULL){  *p=7;  cout << p << endl;}
對於使用 free 的情況,常常定義一個宏或者函式 xfree 來代替 free 置空指針:
#define xfree(x) free(x); x = NULL;// 在 C++ 中應使用 nullptr 指代空指針// 一些平台上的 C/C++ 已經預先添加了 xfree 拓展,如 GNU 的 libibertyxfree(p);// 用函式實現,例如 GitHub 上的 AOSC-Dev/Anthon-Starter #9:static inline void *Xfree(void *ptr) {    free(ptr);#ifdef __cplusplus    return nullptr;#else    return NULL;#endif}q=Xfree(q);
所以動態分配記憶體後,如果使用完這個動態分配的記憶體空間後,必須習慣性地使用delete操作符去釋放它。

相關詞條

熱門詞條

聯絡我們