C++ c++;std::ios_base::故障异常

C++ c++;std::ios_base::故障异常,c++,linux,c++11,exception,iostream,C++,Linux,C++11,Exception,Iostream,标准(N3337)规定(27.5.3.1.1类ios_base::failure): 类失败定义了所有对象类型的基类 iostreams库中的函数作为异常抛出以报告 在流缓冲区操作期间检测到错误 我有一个简单的测试程序,在使用std::ostringstream时模拟受限资源环境: #include <sys/time.h> #include <sys/resource.h> #include <errno.h> #include <stdlib.h&

标准(
N3337
)规定(
27.5.3.1.1类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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,const char*argv[]
{
极限;
limit.rlim_cur=limit.rlim_max=268435456;
if(设置限制(限制和限制)){

std::cerr您正在创建的错误情况本身并不是由流缓冲区操作引起的错误。在某些情况下,您只是耗尽了内存,流的分配器将抛出一个
错误的alloc
。这是您看到的异常


是否应该将
bad\u alloc
作为ios\u base::failure重新调用是有争议的,因为流操作最终会失败。不过,在这种情况下出现
bad\u alloc
的情况并不奇怪。

os因为异常不是由iostreams库引发的,而是由内存分配器引发的,不是吗重新捕获并打包到std::ios_base::failure异常中?我使用的是iostream,而不是内存分配器。您可能会这样认为,但不,标准不要求这样做。还有一个问题是,在引发
坏的\u alloc
后,可能没有任何空间来创建另一个异常。libc++包装std::坏的\u alloc INTO STD::IOSKBASI::但是异常错误代码和值。抱歉,这是为什么我把它作为注释而不是作为答案来回答的。实际上,它确实对你有帮助。很久以前C++中就用这种方式来表示标准头,我只是想指出那些寻求他们的SOLU的未来新手。我无意中发现了这个问题。至少在libc++和libstdc++之间,行为是不同的。libc++捕获std::bad_alloc并返回std::ios_base::failure以丢失原始异常详细信息。因此,没有可移植的方法来准确确定enome条件并以某种特殊方式处理它(例如从DSS段记录一些常量字符串)。