的Visual Studio(Dinkumware的?)使用的std::exception
一個實現,它包含消息內部存儲†。 (完成接受字符串的非標準構造函數)。
因此,實際上不需要虛擬調度來獲取錯誤消息,它可以在任何切片中生存。
更正統的實現將確實打印一個通用的異常消息,因爲派生的對象被切掉。 (實際上,MS取得了std::exception
和std::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";
}
};
這裏,切片會影響您的結果。 (也就是說,畢竟這是總是按照參考)
你只是試圖在你的程序中分配=〜1.9375GB。你正在編譯32位?你的機器裏有甚麼RAM? – FailedDev
@GMan編譯器是MS VS 2008 – Belloc