new 表达在 try 块抛出a bad_alloc我的电脑中的例外。

请注意,捕获子句按值接收异常对象,而不是通过引用。怎么来的 e.what() 印刷 "bad allocation" ?我以为它会切成薄片。

#include <iostream>

int main()
{
    try
    {
        int* p = new int[0x1F000000];
    }
    catch(std::exception e)
    {
        std::cout << e.what() << std::endl;
    }
}
有帮助吗?

解决方案

Visual Studio(Dinkumware?)使用 std::exception 其中包含内部存储†消息。 (配有接受字符串的非标准构造函数。)

因此,实际上不需要虚拟调度来获取错误消息,它可以幸免于任何切片。

更正统的实现确实会打印一般的异常消息,因为派生对象已切片。 (有效地,MS做了 std::exceptionstd::runtime_error 相等的。这没什么错,因为 std::exception::what 是实现定义的,但它解释了您的结果。)


†此处的内部存储空间宽松。它没有内部 缓冲, ,但它有一个 const char*bool. 。这 const char* 指向消息(返回值 what())和 bool 是确定是否应删除缓冲区的标志。

就像这样:

class msvc_exception // for exposition
{
public:
    msvc_exception(const char* msg) :
    mMsg(msg),
    mDoDelete(false)
    {}

    msvc_exception(const std::string& msg) :
    mMsg(copy_string(msg)),
    mDoDelete(true)
    {}

    virtual ~msvc_exception()
    {
        if (mDoDelete)
            delete [] mMsg;
    }

    virtual const char* what() const throw()
    {
        return mMsg ? mMsg : "unknown";
    }

private:
    const char* copy_string(const std::string& str)
    {
        const char* result = new char[str.size() + 1];

        std::copy(str.begin(), str.end(), result);
        result[str.size()] = 0; // null-terminate

        return result;
    }
};

你现在看到了 bad_alloc 这样的工作:

    class msvc_bad_alloc : // for exposition
        public msvc_exception
    {
    public:
        msvc_bad_alloc() :
        msvc_exception("bad_alloc") // note: a static string, no dynamic storage
        {}
    };

切片不会影响消息,因为基类中的消息“存在”。

其他编译器,例如GCC和LLVM,更直接地实现了它:

class orthodox_exception
{
public:
    orthodox_exception(){}
    virtual ~orthodox_exception() {}

    virtual const char* what() const throw()
    {
        return "orthodox_exception";
    }
};

class orthodox_bad_alloc :
    public orthodox_exception
{
public:
    const char* what() const throw()
    {
        return "orthodox_bad_alloc";
    }
};

在这里,切片会影响您的结果。 (也就是说,毕竟:始终通过引用捕获。)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top