为什么我的WinCE应用程序中没有std :: bad_alloc?

时间:2011-12-05 16:53:56

标签: c++ assembly windows-ce arm bad-alloc

根据C ++标准,operator new在分配失败时应throw std::bad_alloc();

为了测试这种行为,我提出了以下代码:

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

问题是,出乎意料的是,每当我在Windows Mobile 2003(Windows CE 4.2)上运行时,我都会得到nullptr

编译器是针对ARM的Microsoft(R)C / C ++优化编译器版本14.00.60131所以我认为不是编译器不符合标准的情况。

我还尝试在给定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       <----   

不应该有系统调用吗?难道不是更复杂吗?任何人都可以帮忙调查这个吗?

1 个答案:

答案 0 :(得分:3)

这听起来很像MSVC6.0的行为,这在平台时代给出的并不奇怪。你可以在这里阅读更多相关内容。

MSDN Magazine September 2003 (ctrl-f表示bad_alloc)

你总是可以覆盖Big的new运算符但是我会反对它,只是接受它不是很好的实现,并继续尝试捕获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
}