----在上一篇c專題指針文章中,咱們介紹了什麼是指針,文章裏面從普通變量進而引出指針的概念,這樣對指針的理解有必定的幫助(其實最好的理解,就是要明白硬件裏面的內存原理,這是理解指針最好的地方,就比如說會彙編語言的人來去理解指針這裏跟不會指針的人去理解,會有很大的差別的,在學彙編的時候,會接觸到好多有關計算機裏面內存的大話題,這個對於搞彙編的來講,掌握了彙編,對理解指針的原理很是容易;而大部分人(固然也包括我本身),剛開始學指針,是真的很是吃力,學了一陣子,感受是學會了,可是一段時間沒有去接觸指針,再次來看指針的話,感受一臉懵逼,好像沒學過同樣,不知道你們有沒有我這樣的經歷,哈哈哈;這裏指出不是鼓勵你們去學花太多時間在彙編上(我的觀點,如今出來上班,好少會搞彙編開發,你搞stm32和一些稍微功能強大的芯片,拿彙編去寫,那簡直不敢想象,並且也沒聽過誰這樣幹過),其實仍是當你用到的時候再去學,很快上手的,就是有好多彙編指令要記,若是你一遍學一遍用,反而會學的更快,理解的更深,並且如今對理解一些高級芯片裏面的啓動代碼會很是有幫助的)。好了,廢話太多,來進入主題!html
1、空指針:
c++
一、什麼是空指針?
程序員
在C語言中,若是一個指針不指向任何數據,咱們就稱之爲空指針,用NULL表示,例如:web
1 int *a = NULL;
NULL在C/C++中定義爲:
微信
1 #ifdef _cplusplus // 定義這個符號就表示當前是C++環境
2 #define NULL 0 // 在C++中NULL就是0
3 #else
4 #define NULL (void *)0 // 在C中NULL是強制類型轉換爲void *的0
5 #endif
說明:a、在C語言中,int *p;你能夠p = (int *)0;可是不能夠p = 0;由於類型不相同。因此NULL的實質其實就是0,而後咱們給指針賦初值爲NULL,其實就是讓指針指向0地址處。爲何指向0地址處?2個緣由。第一層緣由是0地址處做爲一個特殊地址(咱們認爲指針指向這裏就表示指針沒有被初始化,就表示是野指針);第二層緣由是這個地址0地址在通常的操做系統中都是不可被訪問的,若是C語言程序員不按規矩(不檢查是否等於NULL就去解引用)寫代碼直接去解引用就會觸發段錯誤(下面講野指針有舉例子),這種已是最好的結果了。app
b、通常在判斷指針是否野指針時,都寫成if (NULL != p)而不是寫成 if (p != NULL)緣由是:若是NULL寫在後面,當中間是==號的時候,有時候容易忘記寫成了=,這時候其實程序已經錯誤,可是編譯器不會報錯。這個錯誤(對新手)很難檢查出來;若是習慣了把NULL寫在前面,當錯誤的把==寫成了=時,編譯器會報錯,程序員會發現這個錯誤(這裏本身昨天就在這裏犯了低級錯誤)。ui
1、野指針:
url
一、什麼是野指針?
spa
簡單來說它就是指針指向的位置是不可知的(隨機的、不正確的、沒有明確限制的),想必有必定基礎的好友,必定看過這樣的代碼:操作系統
1 #include <stdio.h>
2 int main()
3{
4int *a;
5 *a=9;
6
7 return 0;
8
9 }
說明:這裏是在gcc編譯器下,會出現段錯誤(Sgmentation fault);可是在dev--c++上是不會報錯的。由於指針變量在定義時若是未初始化,值也是隨機的。指針變量的值其實就是別的變量(指針所指向的那個變量)的地址,因此意味着這個指針指向了一個地址是不肯定的變量,這時候去解引用就是去訪問這個地址不肯定的變量,因此結果是不可知的。
二、野指針的危害:
a、指向不可訪問(操做系統不容許訪問的敏感地址,譬如內核空間)的地址,結果是觸發段錯誤,這種算是最好的狀況了。
b、指向一個可用的、並且沒什麼特別意義的空間(譬如咱們曾經使用過可是已經不用的棧空間或堆空間),這時候程序運行不會出錯,也不會對當前程序形成損害,這種狀況下會掩蓋你的程序錯誤,讓你覺得程序沒問題,實際上是有問題的。
c、指向了一個可用的空間,並且這個空間其實在程序中正在被使用(譬如說是程序的一個變量x),那麼野指針的解引用就會恰好修改這個變量x的值,致使這個變量莫名其妙的被改變,程序出現離奇的錯誤。通常最終都會致使程序崩潰,或者數據被損害。這種危害是最大的。
------小結: 指針變量若是是局部變量,則分配在棧上,自己聽從棧的規律(反覆使用,使用完不擦除,因此是髒的,本次在棧上分配到的變量的默認值是上次這個棧空間被使用時餘留下來的值),就決定了棧的使用多少會影響這個默認值。因此咱們要避免這種狀況發生。
三、怎樣來避免野指針的出現?
野指針的錯誤來源就是指針定義了之後沒有初始化,也沒有賦值(總之就是指針沒有明確的指向一個可用的內存空間),而後去解引用。所以我的推薦你們通常經常使用的方法:
第一點:定義指針時,同時初始化爲NULL
第二點:在指針解引用以前,先去判斷這個指針是否是NULL
第三點:指針使用完以後,將其賦值爲NULL
第四點:在指針使用以前,將其賦值綁定給一個可用地址空間
1 #include <stdio.h>
2 int main()
3 {
4 int a;
5 int *b=NULL;
6 b=&a;// 正確的使用指針的方式,是解引用指針前跟一個絕對可用的地址綁定
7 if(NULL != b)
8 {
9 *b=8;
10 }
11 b=NULL;
12 return 0;
13 }
註明:通常來講,定義一個指針都會給初始化一個有效地址來操做。
3、總結:
如今看完文章,你應該對指針的使用必定要注意給初始化,不然就會出現問題。再次強調一下:void 指針與空指針 NULL 不一樣,NULL 說明指針不指向任何數據,是「空的」;而 void 指針實實在在地指向一塊內存,只是不知道這塊內存中是什麼類型的數據。
---歡迎關注公衆號,能夠查看往期的文章:
加我我的微信,而後拉進交流羣(對文章中寫有不對的地方,能夠批評指出,虛心你向您學,一塊兒進步。羣裏只能討論技術方面的,發廣告,馬上飛機):
本文分享自微信公衆號 - TXP嵌入式(txp1121518wo-)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。