天天看點

野指針 空指針

關于空指針NULL、野指針、通用指針

首先說一下什麼是指針,隻要明白了指針的含義,你就明白null的含義了。 

假設 有語句 int a=10; 

那麼編譯器就在記憶體中開辟1個整型單元存放變量a,我們假設這個整型單元在記憶體中的位址是 0x1000;那麼記憶體0x1000單元中存放了資料10,每次我們通路a的時候,實際上都是通路的0x1000單元中的10. 

現在定義:int *p; 

p=&a; 

當編譯器遇到語句int *p時,它也會在記憶體中給指針變量p配置設定一個記憶體單元,假設這個單元在記憶體的編址為0x1003;此時,0x1003中的值是不确定的,(因為我們沒有給指針指派),當編譯器遇到了p=&a時,就會在0x1003單元中儲存0x1000,請看,這就是說:(指針變量p代表的)記憶體單元0x1003存放了變量a的記憶體位址!用通俗的話說就是p指向了變量a。 

p=NULL,就是說:記憶體單元0x1003不存放任何變量的記憶體位址。

删除一個new了的數組。有必要的話。比如非标準的類( new CMyClass),在Type *p = new Type[N]; delete []p;的最後最好再加一句: p = NULL

空指針是一個特殊的指針值,也是唯一一個對任何指針類型都合法的指針值。指針變量具有空指針值,表示它當時處于閑置狀态,沒有指向有意義的東西。空指針用0表示,C語言保證這個值不會是任何對象的位址。給指針值賦零則使它不再指向任何有意義的東西。為了提高程式的可讀性,标準庫定義了一個與0等價的符号常量NULL. 程式裡可以寫 p = 0; 或者 p = NULL; 兩種寫法都把p置為空指針值。相對而言,前一種寫法更容易使讀程式的人意識到這裡是一個指針指派。

我們印象中C語言的指針都有類型,實際上也存在一種例外。這裡涉及到通用指針,它可以指向任何類型的變量。通用指針的類型用(void *)表示,是以也稱為void 指針。

int n=3, *p;
void *gp;
gp = &n;
p=(int *)gp1;
           

野指針,也就是指向不可用記憶體區域的指針。通常對這種指針進行操作的話,将會使程式發生不可預知的錯誤。 

“野指針”不是NULL指針,是指向“垃圾”記憶體的指針。人們一般不會錯用NULL指針,因為用if語句很容易判斷。但是“野指針”是很危險的,if語句對它不起作用。野指針的成因主要有兩種:

一、指針變量沒有被初始化。任何指針變量剛被建立時不會自動成為NULL指針,它的預設值是随機的,它會亂指一氣。是以,指針變量在建立的同時應當被初始化,要麼将指針設定為NULL,要麼讓它指向合法的記憶體。

二、指針p被free或者delete之後,沒有置為NULL,讓人誤以為p是個合法的指針。别看free和delete的名字惡狠狠的(尤其是delete),它們隻是把指針所指的記憶體給釋放掉,但并沒有把指針本身幹掉。通常會用語句if (p != NULL)進行防錯處理。很遺憾,此時if語句起不到防錯作用,因為即便p不是NULL指針,它也不指向合法的記憶體塊。例:

char *p = (char *) malloc(100);

strcpy(p, “hello”);

free(p); // p 所指的記憶體被釋放,但是p所指的位址仍然不變

if(p != NULL) // 沒有起到防錯作用

strcpy(p, “world”); // 出錯
           

另外一個要注

意的問題:不要傳回指向棧記憶體的指針或引用,因為棧記憶體在函數結束時會被釋放。 

指針是個很強大的工具,可是正因為它太強大,是以要操作它不是件易事。操作不當造成的野指針,甚至會引起系統當機等比較嚴重的後果。  如果程式定義了一個指針,就必須要立即讓它指向一個我們設定的空間或者把它設為NULL,如果沒有這麼做,那麼這個指針裡的内容是不可預知的,即不知道它指向記憶體中的哪個空間(即野指針),它有可能指向的是一個空白的記憶體區域,可能指向的是已經受保護的區域,甚至可能指向系統的關鍵記憶體,如果是那樣就糟了,也許我們後面不小心對指針進行操作就有可能讓系統出現紊亂,當機了。是以我們必須設定一個空間讓指針指向它,或者把指針設為NULL,這是怎麼樣的一個原理呢,如果是建立一個與指針相同類型的空間,實際上是在記憶體中的空白區域中開辟了這麼一個受保護的記憶體空間,然後用指針來指向它,那麼指針裡的位址就是這個受保護空間的位址了,而不是不可預知的啦,然後我們就可以通過指針對這個空間進行相應的操作了;如果我們把指針設為NULL,我們在頭檔案定義中的 #define NULL 0 可以知道,其實NULL就是表示0,那麼我們讓指針=NULL,實際上就是讓指針=0,如此,指針裡的位址(機器數)就被初始化為0了,而記憶體中位址為0 的記憶體空間……不用多說也能想象吧,這個位址是特定的,那麼也就不是不可預知的在記憶體中亂指一氣的野指針了。   還應該注意的是,free和delete隻是把指針所指的記憶體給釋放掉,但并沒有把指針本身幹掉。指針p被free以後其位址仍然不變(非NULL),隻是該位址對應的記憶體是垃圾,p成了“野指針”。如果此時不把p設定為NULL,會讓人誤以為p是個合法的指針。用free或delete釋放了記憶體之後,就應立即将指針設定為NULL,防止産生“野指針”。記憶體被釋放了,并不表示指針會消亡或者成了NULL指針。(而且,指針消亡了,也并不表示它所指的記憶體會被自動釋放。)   最後,總結一下野指針的的成因吧: 1、指針變量沒有被初始化。任何指針變量剛被建立時不會自動成為NULL指針,它的預設值是随機的,它會亂指一氣。 2、指針p被free或者delete之後,沒有置為NULL,讓人誤以為p是個合法的指針。 3、指針操作超越了變量的作用範圍。這種情況讓人防不勝防

轉載位址:http://www.360doc.com/content/14/0305/22/11712807_358066638.shtml

上一篇: 空指針