野指針與'關鍵字'NULL
一、NULL是什麼?
在C/C++中的標準定義:
#ifdef __cplusplus //條件編譯,判斷是c++還是c環境
#define NULL 0 //c++環境
#else
#define NULL ((void *)0) //c語言環境
#endif
#endif
在c語言中的NULL就被替換成了((void *)0),這個整體表示的是一個指針,即是指向0地址的viod類型的指針。
所以我們可以理解爲NULL的本質就是0,這個0要看做地址,即是0x00000000。
NULL爲什麼出現,就得明白什麼是野指針了。
注:雖然C標準沒有說空指針與指向內存地址0的指針相同,但是分析之後是可以這樣理解的。(NULL又稱爲空指針常量)
二、野指針
1.什麼是野指針
又叫迷途指針,即指針指向的地址是隨機的。(不指向任何合法的對象的指針)
2.野指針的出現
指針變量在定義後,不去初始化。這個時候,值就是隨機的。這時候這個指針變量就是野指針。
比如在棧裏定義了一個指針變量,即棧給這個指針變量分配了一個內存,而這個內存裏存的值就是該指針指向的地址,然而棧是髒的(反覆使用,不擦除),並不知道地址裏存的什麼數,也就不知道指針指向了哪裏。
3.野指針的危害
指針變量在定義後,不去初始化,這個時候,值就是隨機的,即指向了隨機的一段內存。我們再去解引用時,就是去訪問一個隨機地址,那麼會有什麼樣的後果也是未知的。
一般有三種情況:
①指向了不可訪問的地址(系統不允許訪問的地方)
這種情況是最好的,因爲程序會報段錯誤,無法執行。
②指向了可用的,暫時沒有用到的地方(譬如程序沒有用到的堆棧地址)
這種情況運行時沒問題,也不會報錯。但是實際上程序是有問題的,假如之後程序由於野指針出現了bug,就死活找不到原因了。
③指向了可用的,並且是程序中正在被使用的地方
這種情況野指針的解引用可能就會導致指向的那段內存的值被修改,出現一些離奇的錯誤,導致程序崩潰,數據破壞,損壞。
打個比方:野指針就是個山賊,隨機的搶劫過路商隊。
第一種情況就是
(不可訪問的地址)大型商隊保鏢太強,山賊(野指針)正準備搶劫就被幹掉了,並向後面(我們)的商隊發出了警告
第二種情況就是
(可以訪問,暫時沒用使用的地址)小型商隊,山賊就直接搶了,暫時並不影響繞路的我們。
第三種情況就是
(程序正在使用)我們的商隊,山賊可能搶的可能我們沒法活下去(程序崩潰)
4.怎麼去避免野指針
在指針的解引用之前,一定確保指針指向一個絕對可用的空間。
這時候NULL出現的很及時,常規做法
①定義指針後,將指針初始化爲NULL。
②指針使用之前綁定一個可用地址。
③在指針解引用前,去判斷是否爲NULL。
④使用完,後賦值爲NULL。
1 int a = 1;
2 int *p = NULL; //定義指針並初始化爲NULL
3 p = &a; //綁定一個可用地址
4
5 if (NULL != p) //判斷是否不等於NULL
6 {
7 *p = 10; //解引用
8 }
9
10 p = NULL; //使用完,重新賦值爲NULL
注意(小技巧):
一般將判斷指針是否相等時,不寫成if (p == NULL),而寫成if (NULL == p),原因是== 與 = 的誤錯,程序的意思會不一樣。等號少寫後,if (p = NULL)不會報錯,if (NULL = p)會報錯。
三、NULL的作用
①讓野指針指向一個 '安全的0地址處'
大部分cpu中,內存0地址處不能隨便訪問的,所以避免野指針的誤傷,指向0地址後的使用就會報段錯誤。幫助我們找錯誤。
②特殊標記,即增加程序的可讀性。
表示指針是個野指針。
四、各個零之間的區別('\0' '0' 0 NULL)
①'\0'是個轉義字符,ASCII編碼值是0,本質就是0.
'\0'用法是C語言字符串的結尾標誌
②'0'是個字符,ASCII編碼值是48,即是48
'0'是字符0,獲取ASCII編碼值
③0是數字0,本質也是0
比較一個int類型的數字是否等於0,或者給變量賦值。
④NULL是個表達式((void *)0),強制轉換爲void * 的0,本質也是0
用來比較指針是否是一個野指針
作者:Devil丶wei
出處:https://blog.csdn.net/qq_38190041
版權聲明:本文版權歸作者,轉載請標註文章作者與出處