2011-12-05 45 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

相关问题