指針初始化為NULL的作用


關於空指針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、指針操作超越了變量的作用范圍。這種情況讓人防不勝防。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM