根据 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
block 中手动 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 <----
不应该有任何系统调用吗?不应该更复杂吗?任何人都可以帮助调查这个吗?
最佳答案
这听起来很像 MSVC6.0 的行为,考虑到平台的年龄,这并不奇怪。您可以在此处阅读更多相关信息。
MSDN Magazine September 2003 (bad_alloc 的 ctrl-f)
你总是可以覆盖 Big 的新运算符,但我建议不要这样做,只是接受它不是很好的实现,并继续 try 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
}
关于c++ - 为什么我的 WinCE 应用程序中没有 std::bad_alloc?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8388814/