【发布时间】:2011-12-05 16:53:56
【问题描述】:
根据 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。
编译器是 Microsoft (R) C/C++ Optimizing Compiler Version 14.00.60131 for ARM,所以我认为编译器不符合标准的情况并非如此。
我还尝试在给定的try 块内手动throw std::bad_alloc()(并且成功,因此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 <----
不应该有任何系统调用吗?不应该更复杂吗?有人可以帮忙调查一下吗?
【问题讨论】:
-
可能不符合标准,因为异常被视为低性能系统的两项费用。
-
假设
Big没有重载的new运算符,这绝对是不合格的。试试struct Big2 { char big[10*1024*1024]; };只是为了确定。您可以考虑改用new (std::nothrow) Big,只是为了提醒您这是您的行为。
标签: c++ assembly windows-ce arm bad-alloc