C++中未抛异常却进入catch块及无运行时错误的疑问
问题分析与解答
咱们先把你的代码里的关键行为拆解清楚,再逐个回答你的问题:
1. 为什么没有出现运行时错误(程序崩溃)?
你预期new int[i]会触发程序崩溃,但实际上程序正常执行了——核心原因是你捕获了异常,阻止了程序崩溃。
当你写new int[i]时,这里的i是int类型的-1,会被隐式转换为std::size_t(C++中new[]要求的数组大小类型是无符号的std::size_t)。-1作为有符号整数转成无符号后,会变成std::size_t的最大值(比如64位系统下是18446744073709551615)。尝试分配这么大的int数组必然会失败,此时默认的new操作会抛出std::bad_alloc异常。
但你的代码里用catch (exception& e)捕获了这个异常,程序会跳转到catch块执行后续逻辑,而不是直接崩溃。这就是程序没有出现运行时错误的原因——异常被你正确处理了。
2. 未抛出异常的情况下,程序为何会进入catch块?
这其实是你的误解:程序实际上抛出了异常,所以才会进入catch块。
你可能混淆了两种new的行为:
- 默认的
new(也就是你代码里用的):分配失败时会抛出std::bad_alloc异常; nothrow版本的new(new(std::nothrow) int[i]):分配失败时不会抛出异常,而是返回nullptr。
你的代码用的是默认抛出异常的new,当内存分配失败时异常被抛出,自然会进入catch块执行。你看到的“程序正常执行”其实是异常被处理后的正常流程,并非没有抛出异常。
额外验证小技巧
如果你想确认确实是std::bad_alloc被捕获,可以在catch块里打印异常信息:
catch (exception& e){ cout << "coming here: " << e.what() << endl; // 会输出类似"std::bad_alloc"的信息 c = new int[1]; b++; }
这样你就能直观看到是哪个异常被捕获了。
内容的提问来源于stack exchange,提问作者SNR_BT
相关产品推荐
相关产品推荐

