``'e.什么()``''()打印“不良分配”?
-
26-10-2019 - |
题
这 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::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";
}
};
在这里,切片会影响您的结果。 (也就是说,毕竟:始终通过引用捕获。)
不隶属于 StackOverflow