2015-12-28 69 views
0

我已經看了全部,似乎有很多關於assert的混合視圖。例如,如果我malloc'ing一個指針,要確保它被正確地分配我會寫:的處理錯誤檢查與斷言

p = malloc(sizeof(int)); 
assert(p) 

代替:

p = malloc(sizeof(int)); 
if (p == NULL) 
{ 
... send error message 
} 

我知道,與斷言它會結束程序,但對於測試目的 - 我想知道的是絕對最安全的方式是什麼:

  1. 測試的東西像一個malloc正在做正確。
  2. 處理一個錯誤,如果東西不是malloc'd正確。
+0

請記住'assert'往往是無操作在釋放模式。 – juanchopanza

+0

絕對選項2,'assert'用於調試目的。 – manetsus

+0

那麼,如果你想檢查發佈模式中的錯誤,顯然不是。 – juanchopanza

回答

1

  1. 測試失敗:如果所請求的內存量不能提供給程序
    malloc函數是由C標準需要返回NULL。

    這意味着如果malloc的返回值爲非NULL,則可以確定 ALL的內存已正確分配。

    檢查是否爲NULL返回值是確定的malloc是否是成功的唯一途徑。如果斷言失敗,則可以使用assert函數來停止程序,但在程序的產品發行版中, 必須存在其他錯誤處理。

  2. 處理故障:
    如果返回值是NULL,則使用errno變量來確定發生故障的原因。變量errno也是C標準的一部分。

    對於Linux,這裏是值的列表errno可以設置爲:

    http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html

  3. 重要:malloc失敗是一個嚴重的錯誤。如果在 程序執行中發生這種情況,請勿嘗試在程序中繼續執行其他 功能。 停止(從出口)的程序,只要一個錯誤已被記錄並 上報程序的用戶,如下所示:

    您應該使用exit功能與非零返回 值到通知程序用戶該程序退出 並顯示錯誤狀態。函數exit是ALSO C語言標準的一部分。

    此外,在退出程序之前,請確保已分配 的所有其他內存(在malloc失敗之前)已正確解除分配。

+0

詳細信息:請注意,使用'n == 0',C允許'malloc(n)'返回NULL,並且它不是內存不足的情況。在這種情況下,「errno」不一定會改變。 Linux和其他操作系統可能會另外指定。 – chux

2

召回assert()通常只在程序調試構建而不是發佈版本活躍。

分類的潛在錯誤分成組:

1)必須處理運行時錯誤。
assert()在這裏不好,代碼必須處理錯誤。

2)應該處理的運行時錯誤沒有定義的補救措施。
assert()這裏也不明智。代碼應該發信號(留下錯誤信息)並退出。

3)運行時錯誤,沒有簡單的重新過程來處理它們。
assert()可能在這裏使用。現在,當程序錯誤/死亡/掛起時,我們沒有任何東西。如果可能的話,推薦代碼應該像#2那樣發出信號。

4)編譯時間錯誤。
assert(sizeof(int)*CHAR_BIT >= 32)是一個很好的示例用法。假設構建將在調試模式下發生是合理的。即使這樣,部署的源代碼也存在一定風險,即現場用戶可能會跳過調試版本,因此建議僅對內部代碼使用assert()

assert()是C工具箱中的一個工具。它有它的用途 - 和錯誤的用途。


隨着malloc(),我已經對禁止直接使用C LIB malloc()和替代項目特定的代碼像my_malloc_never_fail()my_malloc_may_fail()其中有錯誤處理和指標,許多項目的工作。正如@Weather Vane評論說的,良好的錯誤句柄是具有挑戰性的。