2013-02-26 59 views
7

調用空函數指針的行爲是什麼?NULL函數指針

void (*pFunc)(void) = NULL; 
pFunc(); 

爲什麼建議將尚未使用的函數指針初始化爲NULL?

+1

就像一個正常的指針,我想你會得到一個段錯誤。 – Rerito 2013-02-26 13:06:59

+1

http://stackoverflow.com/questions/10014284/what-does-null-function-pointer-in-c-mean – Suri 2013-02-26 13:10:42

+1

這兩個是指向相同的問題:-) – 2013-02-26 13:12:57

回答

7

在C和C++,這就是所謂的undefined behaviour,這意味着這可能導致分段故障,沒有或任何這樣的情況下,會造成基礎你的編譯器,你運行這個代碼的操作系統,環境(等等)的含義。

初始化指向函數的指針或一般指向NULL的指針有助於一些開發人員確保其指針未初始化並且不等於隨機值,從而防止它們意外地將其解除引用。

+0

如果SEGFAULT得到保證會是很好。 – Vorac 2013-02-26 13:29:29

+1

這將導致99%的情況和許多系統/體系結構出現分段錯誤。然而,標準並沒有明確說明它會發生。 – 2013-02-26 13:35:33

+0

我認爲這是「未詳細說明」的行爲,但並不真正未定義。如果內存0x0是可尋址和「可執行的」...... – 2013-02-26 15:18:34

0

與初始化指向NULL的「正常」(數據)指針相同的原因是可取的:因爲它可能會使一些錯誤更容易追蹤。這是否有用與否意見的過程中變化:-)

1
  1. 當你嘗試訪問NULL時有什麼好處? 對於數據以及代碼,以下情況屬實:當您嘗試讀取NULL(或從0到 4096,即至少第一頁的段)時,將發生以下情況: 。這個根源在於 操作系統和微處理器分割/分頁架構

    當您嘗試訪問NULL(或0)的地址,在任何數據或代碼 段的,它會導致分段錯誤(這實際上是一個殺手 頁面錯誤)。第一頁的部分被視爲超出虛擬地址空間(或無效的 部分)。這是有目的的,第一頁 保持無效(或不存在),因此指針 包含的至少一個地址在執行 時可以在程序中被表示爲無效。

    第一頁(其中包含虛擬地址0, NULL)的頁面描述符的第一位「存在」爲0(表示其無效頁面)。現在如果 您嘗試訪問空指針(0地址),將會導致頁面錯誤 頁面不存在,並且操作系統將嘗試處理這個頁面錯誤 。當頁面錯誤處理程序發現它試圖訪問 1st頁面時,它被視爲虛擬地址 空間的無效部分,它會殺死該進程。這是關於用戶空間的過程。如果 您嘗試訪問系統進程中的NULL指針(內核級代碼), 它會使您的操作系統崩潰的系統。

    鏈接:http://en.wikipedia.org/wiki/Page_fault#Invalid http://en.wikipedia.org/wiki/Memory_protection#Paged_virtual_memory http://pdos.csail.mit.edu/6.828/2005/readings/i386/s05_02.htm

    以上是足夠的BT,我覺得你應該閱讀以及 http://www.iecc.com/linker/linker04.txt

  2. 爲什麼函數指針被初始化爲NULL? 雖然如果你試圖用NULL調用它會給頁面/段的錯誤。 NULL表示其無效功能。如果它 包含任何垃圾地址,但在有效虛擬地址空間 代碼部分,我認爲在該地址的任何代碼將被調用,哪個 可能會更加災難(在實時系統的情況下spl)。 初始化funcp = funct_foo_name + 1;現在使用 函數指針調用函數。函數指針指向代碼段的有效虛擬地址空間 。 bt函數將從不正確的地方 開始執行。這可能會導致錯誤的代碼執行或錯誤的訂單號碼 。

+1

你讓太多的假設不一定成立。我曾在地址0與地址42890沒有任何區別的平臺上工作。 – 2013-02-26 18:35:50

+1

隨着[十誡](http://www.lysator.liu.se/c/ten-commandments.html)教導我們, 「你不應該遵循NULL指針,因爲混亂和瘋狂在最後等待着你。」 – vonbrand 2013-02-26 19:11:28

+0

@NikBougalis:你是真的。我的意思是第一頁或無效地址範圍0到4096(這是x386的標準頁面大小)是初始無效虛擬地址空間。當我認爲它是一個操作系統相關的東西時,它認爲虛擬地址空間範圍的起始部分有多少是無效的 – 2013-02-27 06:12:04