2015-03-31 67 views
0

我認爲如果在函數中傳遞空指針,就讓它通過gp,我們可以很容易地找到根本原因。但是我的隊友說我們應該避開生產代碼中的gp時間,如果應用程序通常會崩潰,客戶端可能會感到不安,儘管根本原因可能包含在一些空指針保護中。無效的指針處理策略

當您需要驗證指針爲空時,您將使用哪種方法?

HRESULT function(const int* pNumber) 
{ 
    { POINTER CHECK for pNumber... } 
    ... 
} 

方法1 - 忽略無效的情況下

if(pNumber) 
{ 
    int a = *pNumber; 
} 
  • 沒有GP
  • 可能進入異常流量
  • 很難找到根源

方法2 - 斷言指針,在調試模式

assert(pNumber); 
int a = *pNumber; 
  • 月GP警告在釋放模式
  • 從未進入異常流量
  • 容易找到根源

方法3 - 留下調試信息並返回錯誤代碼

if(!pNumber) 
{ 
    OutputDebugString(L"Error Null pointer in function.\n"); 
    return E_POINTER; 
} 
  • 沒有GP
  • 不會進入函數內部異常流量。客戶可以進入異常流出方,如果他忽略E_POINTER返回
  • 默默很難找到根源

方法4 - 拋出一個logic_error例外 - 讓來電者抓

if(!pNumber) 
{ 
    throw std::logic_error("Null pointer of pNumber in function"); 
}; 
  • 否GP
  • 堆棧退出時沒有資源管理(RAII)的代碼序列中可能會發生資源泄漏。
  • 從未進入異常流量
  • 很難找到其中的例外是扔
+0

gp究竟是什麼? – rozina 2015-03-31 06:19:43

+0

一般保護錯誤,通常在您引用無效地址或0x00000000時發生,然後應用程序立即中止或崩潰。 – 2015-03-31 06:21:40

+4

如果你大寫GP,並且至少提到一次你想要的含義,你的問題就會有所改善。也就是說,因爲你使用的是C++,所以顯然是方法5,傳遞一個引用,這將強制調用者首先驗證他們的指針。 – 2015-03-31 06:37:42

回答

2

如果取消引用nullptr,您輸入的未定義行爲的土地。這意味着,你的編譯器沒有義務去做anything sensible,所以這應該真的被避免。它也可能決定,因爲它是非法的,所以它從未發生過,所以它刪除了相應的代碼(從而優化它),並且你有邏輯錯誤而沒有發生一般保護錯誤。

我個人更喜歡assert -case,如果nullptr是絕對無效的,但在這種情況下,參考文獻無論如何都可能更明智。我不認爲有一個總體政策,因爲它嚴重依賴於周圍的邏輯。

0

我priffer方法2

assert(pNumber); 
int a = *pNumber; 

因爲,在調試模式下,您可以輕鬆地識別斷言失敗發生在哪裏。即使在釋放模式下它也確保null值不會繼續進入裏面的函數。用戶不會看到任何異常行爲,應用程序將正常工作。

+2

assert如何影響發佈模式下的程序?我認爲assert在發佈模式下被刪除。 – rozina 2015-03-31 06:21:58

+0

在C++中沒有「調試模式」和「發佈模式」這樣的東西,它們是MSVCisms。然而,如果宏'NDEBUG'是'#defined',那麼'assert()'就會被剝離,而這個宏通常是爲優化(非調試)構建而定義的。 – 2015-03-31 06:42:10

1

異常是一種嚴重的違約行爲,如果您有兩個通過接口進行通信的模塊,這是有意義的。對於一個cpp單元本地的靜態函數來說並不是那麼簡單。考慮訪問過去的數組。它也假定對方會抓住它。

其他都不夠好。

  • assert(pNumber);孤單弱。可能會有一個特定於發佈模式的行爲,並且您不會捕獲它。此外,它是 限於您在調試中測試的輸入範圍(遠遠大於全部的 )。
  • 忽略如上所示的無效情況,就像插入鴕鳥一樣將您的頭插入 地面。
  • OutputDebugString比斷言弱。你最終會讓 的東西滑動錯誤信息,你會習慣很多你 將停止閱讀它們。

所以如果我不使用例外,我將使用

assert(pNumber); 
if(pNumber) 
{ 

} 
else 
{ 
    //Log with a logger which has different logging level to the level you seem fit 
}