2013-01-03 68 views
19

Java和C#以及可能還有其他許多語言都有一個預定義的異常類,當使用null參數時它將不會引發。 C++中有類似的東西嗎?如果沒有,是否有另一個預定義的例外,我可以使用或者我應該定義我自己的嗎?是否存在C++等價的NullPointerException

+9

分割錯誤。 – kmkaplan

+0

FTR,在C#中,除非你想被你的隊友刺傷,否則你不會使用NullReferenceExceptions。 –

+0

在C#中,我使用了一個ArgumentNullException,我的隊友總是對我很好。 –

回答

20

取消引用NULL指針在C++中是未定義的行爲 - 這意味着代碼可能看似工作。不能保證引發異常。您可以使用

std::invalid_argument

異常(提供一個有意義的值給它 - "p is NULL"),但你必須做的檢查自己。

+0

謝謝,這是我正在尋找的答案。 –

9

通常,在C++(或C爲那件事),你從來沒有取消引用一個NULL指針。這樣做有未定義的行爲(可能是我知道的任何實現的段錯誤,但根據標準可能會發生任何事情)。這在其他語言中可能也是一件壞事,但我不知道那些足以說明這一點。

最好防止出現這種情況,而不是試圖從中恢復(無論如何C或C++都無法完成)。

了以往的模式,防止一些相關的編程錯誤是使用assert()內部功能機構,如:

int foo(int* myint) 
{ 
    // Ensure myint is not NULL 
    assert(myint); 

    // Do something with myint 
    (*myint)++; 

    return *myint; 
} 

這種assert()通話將被完全忽略的發佈版本,因此在生產沒有成本。他們只是幫助發展。在調試版本上,如果條件不滿足,程序會立即以非常明確的錯誤消息中止。通過調試器運行它,您可以輕鬆檢查調用堆棧以調查確切原因。

+5

在C#中使用Java依靠捕獲空指針也是不好的做法(只有異常來自所有運行時異常的非常高級別的恢復,例如在線程池中)。它們旨在更容易發現編程錯誤。 – Thirler

+0

請注意,如果代碼碰巧是使用NDEBUG定義的(-DNDEBUG)進行編譯,則assert()將被#ifdef'd out。 – daddesio

4

FTR,在C#中你不會使用NullReferenceException s,除非你想被你的隊友刺傷。有一個ArgumentNullException而不是拒絕空參數。 NRE是由運行時引發的,而不是你。

但是請注意,這對於斷言沒有任何實際優勢,因爲您不應該捕捉其中的一個:如果它們被拋出,它們會指示一個錯誤。這些就是Eric Lippert所稱的boneheaded exceptions,它們是你自己的缺點,你的代碼應該專門與他們做任何事情。

2

在C++ dereferencing空指針將導致未定義的行爲,大多數情況下應用程序與段錯誤結束。在Visual Studio中,您可以使用擴展,如結構化異常處理(SEH),它允許捕獲空指針解引用。

2

在幾乎所有涉及錯誤地使用空指針的情況下(特別是對其進行去擴展),C++標準只會使行爲不確定。沒有提供特定的異常類型(並且不會拋出異常)。

雖然這個規則有一個可能的例外。std::function,這是可以用來包裝功能的C++ 11個標準庫模板,可以分配一個空指針:

std::function<void(int)> func = nullptr; 

如果您隨後試圖通過調用由它包裹的功能它會爲func(arg);做一些自變量arg,它會拋出一個std::bad_function_call異常。

當然,這並不完全等同於其他語言的空指針異常,因爲它通常不太適用。

5

C++中沒有用於解引用NULL指針的標準異常。

如果你想要它,你可以自己實現它。在UNIX上設置一個SIGSEGV信號處理程序並從處理程序中引發異常。在Windows上,使用_set_se_translator()API來安裝「結構化異常」處理程序。

相關問題