【发布时间】:2016-08-23 12:44:39
【问题描述】:
标准(N3337)说(27.5.3.1.1 Class ios_base::failure):
类失败定义了所有对象类型的基类 由 iostreams 库中的函数作为异常抛出,以报告 在流缓冲区操作期间检测到错误。
我有一个简单的测试程序,它在使用 std::ostringstream 时模拟受限资源环境:
#include <sys/time.h>
#include <sys/resource.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <sstream>
int main(int argc, const char* argv[])
{
rlimit limit;
limit.rlim_cur = limit.rlim_max = 268435456;
if(setrlimit(RLIMIT_AS, &limit)) {
std::cerr << "Cannot set resource limit: " << strerror(errno) << std::endl;
exit(EXIT_FAILURE);
}
std::ostringstream os;
os.exceptions(std::ostringstream::badbit);
try {
auto iterations = 1024 * 1024 * 1024;
while(iterations && --iterations) os << 'F';
} catch(const std::ios_base::failure& ex) {
std::cerr << "Caught: std::ios_base::failure" << std::endl;
} catch(const std::bad_alloc& ex) {
std::cerr << "Caught: std::bad_alloc" << std::endl;
} catch(...) {
std::cerr << "Caught: ellipsis" << std::endl;
}
return 0;
}
在我的环境(Linux,gcc 5.3.0)中,我在stderr 上获得了Caught: std::bad_alloc。 One of online compilers 显示相同的输出。
问题是:为什么异常类型是std::bad_alloc 而不是std::ios_base::failure?
【问题讨论】:
-
因为异常不是由 iostreams 库引发的,而是由内存分配器引发的?
-
不应该重新捕获并打包在 std::ios_base::failure 异常中吗?我正在使用 iostream 而不是内存分配器。
-
您可能会这么认为,但不,标准并不要求这样做。还有一个问题是,
bad_alloc被激发后,可能没有空间再创建一个异常了。 -
libc++ 将 std::bad_alloc 包装到 std::ios_base::failure 异常中,但丢失了 error_code 类别和值。
-
很抱歉惹恼了您,但这正是我将其发布为评论而非答案的原因。实际上,它确实对您有所帮助;以这种方式使用标准头文件很久以前在 C++ 中已被弃用,我只是想为那些寻求解决方案并偶然发现这个问题的未来新手指出这一点。
标签: c++ linux c++11 exception iostream