2016-09-14 78 views
1

我一直強烈的例外保證測試一個類,特別是在內存不足的情況下發生了什麼,通過隨機發出malloc()返回nullptr。它使用嵌套異常。std :: throw_with_nested()在內存不足條件調用std :: terminate()

比方說,我有以下代碼:

static std::unordered_map<size_t, size_t> map; 
try { 
    map.at(0); // Throws std::out_of_range 
} catch (...) { 
    std::throw_with_nested(std::runtime_error("Input not in map")); // Out of memory here 
} 

std::throw_with_nested()結束了通話std::terminate()

terminate called after throwing an instance of 'std::out_of_range' 
    what(): _Map_base::at 

Program received signal SIGABRT, Aborted. 
0x00007ffff6d96418 in __GI_raise ([email protected]=6) at ../sysdeps/unix/sysv/linux/raise.c:54 
54 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. 
(gdb) bt 
#0 0x00007ffff6d96418 in __GI_raise ([email protected]=6) at ../sysdeps/unix/sysv/linux/raise.c:54 
#1 0x00007ffff6d9801a in __GI_abort() at abort.c:89 
#2 0x00007ffff76d884d in __gnu_cxx::__verbose_terminate_handler()() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
#3 0x00007ffff76d66b6 in ??() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
#4 0x00007ffff76d6701 in std::terminate()() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
#5 0x00007ffff76d5472 in __cxa_allocate_exception() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
#6 0x0000000000425d4c in std::_Throw_with_nested_impl<std::runtime_error, true>::_S_throw<std::runtime_error>(std::runtime_error&&) (
    __t=<unknown type in /path/to/<redacted>, CU 0x2a2a, DIE 0xae780>) at /usr/include/c++/5/bits/nested_exception.h:100 
#7 0x000000000041d09f in std::throw_with_nested<std::runtime_error>(std::runtime_error&&) (__t=<unknown type in /path/to/<redacted>, CU 0x2a2a, DIE 0xa3e18>) 
    at /usr/include/c++/5/bits/nested_exception.h:137 

根據標準這是預期的行爲?就個人而言,它感覺應該只是覆蓋舊的異常,或者如果它不能分配一個嵌套的異常,則拋出std::bad_alloc

回答

0

據我瞭解,中std::nested_exception兩個構造函數和全局函數std::current_exception()noexcept,所以如果有異常的任何一個發生時,動作的唯一允許當然是std::terminate

+0

根據cppreference.com std :: current_exception()將只返回在調用本身引起的異常。 – josefx

+0

@josefx你是對的。這樣就留下了外部異常的構造函數。例如,std :: runtime_error包含一個std :: string。如果拋出期間拋出,我認爲這將終止。 –

+0

雖然堆棧跟蹤指向內部的std :: throw_with_nested,所以std :: runtime_error似乎構造沒有問題(否則它永遠不會有調用std :: throw_with_nested) –

相關問題