2011-12-05 78 views
3

根據C++標準,當分配失敗時operator new應該throw std::bad_alloc();爲什麼我不能在我的WinCE應用程序中獲得std :: bad_alloc?

爲了測試這種行爲,我想出了下面的代碼:

try 
{ 
    for (;;) 
    { 
     Big* p = new Big; 
     if (0 == p) 
     { 
      printf("nullptr"); 
      break; 
     } 
    } 
} 
catch (std::bad_alloc&) 
{ 
    printf("exception"); 
} 

的問題是,出乎意料的是,我得到nullptr每次我在我的Windows Mobile 2003(Windows CE的4.2)運行此。

編譯器是針對ARM的Microsoft(R)C/C++優化編譯器版本14.00.60131,所以我認爲編譯器不符合The Standard的情況。

我也試圖手動throw std::bad_alloc()內給出try塊(和成功所以catch部分應在衰竭new的情況下觸發)。另一件事是set_new_handler(),但也沒有工作。如果重要,我的Big大小爲10MB。

那麼你能告訴我我失蹤了什麼嗎?爲什麼我不能得到std::bad_alloc

編輯1:我不是在尋找如何克服這一點,但爲什麼它首先發生的原因。

編輯2:我已經簡化程序,就像我可以,在我的旅途調試new,並拆卸輸出我得到的是:

 int* p = new int[10]; 
00011010 mov   r0, #0x28 
00011014 bl   00011040  <---- here is the call to operator new 
00011018 str   r0, [sp, #0xC] 
0001101C ldr   r3, [sp, #0xC] 
00011020 str   r3, [sp, #4] 
00011024 ldr   r3, [sp, #4] 
00011028 str   r3, p 

     operator new: 
00011040 ldr   r12, [pc]   <---- 
00011044 ldr   pc, [r12]   <---- what are those? 
00011048 andeq  r3, r1, r0   <---- is it just that? 
0001104C andeq  r1, r1, r4, lsr #11 <---- nothing else to be seen...  
00011050 streqd  r2, [r1], -r0  <---- 

不應該有任何系統電話?它不應該更復雜嗎?任何人都可以幫助調查此問題嗎?

+0

使用調試器來調試'新' – Abyx

+0

可能性差的標準遵從性,因爲例外情況被認爲是低性能系統的兩項開支。 – 111111

+0

假設'Big'沒有重載的'new'操作符,這肯定是不合格的。用'struct big2 {char big [10 * 1024 * 1024]; };'只是爲了確定。你可以考慮使用'new(std :: nothrow)Big'來代替,只是爲了提醒你這就是你得到的行爲。 –

回答

3

這聽起來很像MSVC6.0的行爲,這在平臺時代給出並不令人驚訝。你可以在這裏讀更多關於它的內容。

MSDN Magazine September 2003 (CTRL-F爲bad_alloc的)

你總是可以覆蓋爲大的新的運營商,但我建議不要它,只是接受,這不是很好的實施,並不斷嘗試和catch對於std :: bad_alloc,以防將代碼移植到更好的平臺。

我通常不主張宏,但你可以旋轉一個檢查是否爲null並拋出bad_alloc,這可以但很快然後被刪除,如果你移植你的代碼。 (一個內聯函數可能會做得很好,但對於一個醜陋的問題,真的有時候是一個醜陋的修正是需要的)。

template<PointerType> 
inline void good_alloc(PointerTpye ptr) //throws std::bad_alloc 
{ 
#if BAD_COMPILER //MSVC version number? 
    if(ptr==null) 
    { 
     throw std::bad_alloc; 
    } 
#else 
    //do nothing 
#endif 
} 
+0

實際上,通過提供一個'new'處理函數可以實現'operator new()'拋出,這是通過'set_new_handler()'完成的。 – sharptooth

相關問題