2015-08-23 55 views
3

在以前的節目我用下面的代碼來檢查內存分配失敗,通常不考慮替代方案:C++內存分配與operator new:檢測和處理分配錯誤的方法有哪些?

int* p_int = new int[10]; 
if(!p_int) 
{ 
    // We failed, so exit 
    return EXIT_FAILURE; 
} 

這種方法也記載here

我發現here了語法的參考:

p_int = (nothrow) new int[10]; 

這表明,如果程序員不包括nothrow「說法」,以新的,然後nullptr支票是無效的?它是否正確?或者它依賴於操作系統?

據我所知,newtry-catch塊中沒有什麼意義,除非您可以從中恢復,因爲與此相關的開銷。這是否正確?

+3

第一個代碼是沒有意義的,因爲'new int [10]'如果它返回就永遠不會失敗。 –

+0

@LightnessRacesinOrbit使用try catch語句肯定會有一些開銷。 – user3728501

+0

@ user3728501:爲什麼? –

回答

3

一個new後檢查nullptr是無用的,因爲失敗new不設置指針nullptr

int* p_int = new int[10]; 
if(!p_int) 
{ 
    // error handling 
} 

而失敗newthrow一個std::bad_alloc,所以如果你想嘗試對付它,你需要trycatch

try 
{ 
    int* p_int = new int[10]; 
} 
catch (const std::bad_alloc& e) 
{ 
    std::cout << "Allocation failed: " << e.what(); 
    // deal with it 
} 
+0

我很困惑 - 爲什麼經常建議檢查'nullptr'?第二個參考是否不正確? – user3728501

+0

@ user3728501你應該通常檢查指針是否是'nullptr',然後將它解除引用爲好習慣,我只是說在這種情況下指針將不會成爲'nullptr'。如果你重載operator new **(例如你創建了一個分配器池或其他東西),那麼使用'nothrow'的方法只有**,這意味着你必須定義你的'new'來返回'nullptr'而不是拋出。如果你使用默認的'new',你不能聲明它是'nothrow',因爲它確實可以拋出。 – CoryKramer

+1

@ user3728501:在C++被標準化之前或者在異常支持是C++編譯器的正常特性之前,它可能被*建議了。現在大約20年前。時代在變,C++和現在可用的工具是完全不同的。您引用的2007年的文章事實上是錯誤的,其「將所有指向已刪除內存的指針設置爲0」的建議是IMO完全廢話。一般來說,請使用cppreference。com提供了一個很好的在線參考,並從Scott Meyers或Herb Sutter等着名C++作者那裏獲取書籍。 –

2

是,除非新的無擲版本被使用(並且它不會被重載來做其他事情!)它永遠不會返回null,而是會拋出一個異常。 至於在處理指針時無所不在檢查null,通常這是一個誤導的事情。最多隻能用於調試版本。由於空指針只是通常不好的(不可解引用的)指針的狹義子類,並且它們很少出現在非調試版本中,因此檢查空值只是CPU預熱。例如,庫函數通常不檢查它們的輸入是否爲空值。

+0

Upvote for *「檢查空值只是CPU預熱」* :) –

+0

@ChristianHackl,至少我們在這裏同意) – SergeyA