訪問 NULL 指針錯誤背後的原理

收藏待读

訪問 NULL 指針錯誤背後的原理

前言

說到 NULL 指針大家都是談之色變,第一印象就是 NullPointerException , Segmentation fault 之類的錯誤。NULL 指針大部分情況下會導致程序被終止。但是其實嚴格來說,訪問空指針會產生不可預料的結果。只不過大部分情況是程序被終止。為什麼呢?接下來讓我們來探討訪問 NULL 指針錯誤背後的原理。

NULL 在編譯器中的實現

首先,我們來看看 NULL 指針到底是什麼?

Null 是一個特殊指針值(或是一種對象引用)表示這個指針並不指向任何的對象。

舉一些例子,C/C++ 中的 NULL ,Python 中的 None 等等。大部分 NULL 實現是用 0 代表 NULL ,例如說 C/C++ 。實際上,NULL 的值並不重要,重要的是它代表的含義。例如說,JVM 規範並沒有規定 NULL 的值,不同虛擬機實現可以自己定義 NULL 的值。

總之, NULL 的值取決編譯器實現。

訪問 NULL 指針的過程

C 語言中,NULL 的值是 0,即 NULL == 0 是成立的。我們前面說訪問 NULL 指針的行為會產生不可預料的後果。但是在 Linux 系統中後果是確定的:訪問空指針會產生 Segmentation fault 的錯誤。因此這裡的「不可預料」指的是在不同系統產生的後果不一樣。

讓我們假設現在使用的是 C 語言,運行在 Linux 系統上,以此來分析訪問 NULL 指針的過程。

0
SIGSEGV

可以看到:不需要特定的編譯器實現或者內核的支持,只需要讓一個頁映射到 0x0 的虛擬地址上,就完美的實現了檢測空指針的錯誤。

總結

為了研究這個問題,我查了很多資料。空指針的問題涉及 Linux 內存管理的知識,主要參考了 Robert Love 大神對該 問題 的回答和《深入理解Linux內核》。最大的感悟是帶着問題去看內核的書,你會理解內核為什麼要這麼做,同時可以加深理解和記憶。

總之,空指針的實現取決於編譯器的實現,訪問空指針的後果取決於操作系統的實現。大部分系統類似於 Linux,會產生 Segmentation fault 的錯誤,至於內部實現就要看各個系統的代碼了。

參考資料

What actually happens when dereferencing a NULL pointer?

《深入理解Linux內核》

原文 : ShareHub

相關閱讀

免责声明:本文内容来源于ShareHub,已注明原文出处和链接,文章观点不代表立场,如若侵犯到您的权益,或涉不实谣言,敬请向我们提出检举。