空指針賦值分區

空指針賦值分區

  1. 爲什麼通過空指針讀寫的時候就會出現異常?
  2. 除了NULL表示空指針,是否還有其他的值也是空指針?
  3. 如果還有其他的值,你們這些表示空指針的值都是什麼?爲什麼?

首先解答第一個問題,在windows核心編程第四版的windows的內存結構一章中,表13-1有提到NULL指針分配的分區。其範圍是從0x00000000到0x0000FFFF。這段空間是空閒的,對於空閒的空間而言,沒有相應的物理存儲器與之相對應,所以對這段空間來說,任何讀寫操作都是會引起異常的。

有了上面的解答後,第二個問題就很容易解答了。NULL的定義出現以下幾個地方:

stdio.h文件中

#ifndef NULL 
#ifdef  __cplusplus 
#define NULL    0 
#else 
#define NULL    ((void *)0) 
#endif 
#endif

ios.h文件中

#ifndef NULL 
#define NULL    0 
#endif

windef.h文件中

#ifndef NULL 
#ifdef __cplusplus 
#define NULL    0 
#else 
#define NULL    ((void *)0) 
#endif 
#endif

可見,NULL的值,基本上是用0來表示的,是不是隻能用0呢?在windows xp sp2的系統平臺下,如果執行下面代碼也是會發生異常的:

int * pAddr = (int *)0x0000ffff;

*pAddr = 1;

而下面的代碼是不會出問題的:

int * pAddr = (int *)0x00010000;

*pAddr = 1;

爲什麼呢?在windows xp sp2下發現0x00000000到0x0000FFFF是空閒區間,而0x00010000所處的是進程的私有區間。我想第二個問題應該已經解決了,我想,空指針是程序無論在何時都沒有物理存儲器與之對應的地址。爲了保障“無論何時”這個條件,需要人爲劃分一個空指針的區域,固有上面NULL指針分區。

在第二個問題的基礎上,要解答NULL指針的範圍,那就相對來說容易了,對於在32位x86計算機上運行的windows xp sp2來說,就是從0x00000000到0x0000ffff。爲什麼分配如此大的空間?而在定義NULL的時候,只使用了 0x00000000這麼一個值,這不是浪費嗎?我想,這是操作系統地址空間的分配粒度相關的,windows xp sp2的分配粒度是64KB,爲了達到對齊,空間地址需要從0x00010000開始分配,故空指針的區間範圍有那麼大。

上面的闡述如有問題,希望各位更正,謝謝。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章