为什么 `e.what()` 打印“错误分配”?
在我的计算机中,try
块中的 new
表达式引发了 bad_alloc
异常。
请注意,catch 子句通过值而非引用接收异常对象。为什么e.what()
打印“bad Allocation”
?我还以为会被切片呢
#include <iostream>
int main()
{
try
{
int* p = new int[0x1F000000];
}
catch(std::exception e)
{
std::cout << e.what() << std::endl;
}
}
The new
expression in the try
block throws a bad_alloc
exception in my computer.
Note that the catch clause receives an exception object by value, not by reference. How come e.what()
prints "bad allocation"
? I thought it would be sliced.
#include <iostream>
int main()
{
try
{
int* p = new int[0x1F000000];
}
catch(std::exception e)
{
std::cout << e.what() << std::endl;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Visual Studio(Dinkumware?)使用
std::Exception
的实现,其中包含消息的内部存储†。 (完成一个接受字符串的非标准构造函数。)因此,实际上不需要虚拟调度来获取错误消息,它可以在任何切片中幸存下来。
更正统的实现确实会打印通用异常消息,因为派生对象被切掉了。 (实际上,MS 已使
std::exception
和std::runtime_error
等效。这没有任何问题,因为std::exception 的返回值: :what
是实现定义的,但它解释了您的结果。)†此处的内部存储使用松散。它没有内部缓冲区,但有一个 const char* 和一个 bool。
const char*
指向消息(what()
的返回值),bool
是一个标志,确定缓冲区是否应该被删除。就像这样:
您现在看到
bad_alloc
的工作原理如下:切片不会影响消息,因为消息“存在”在基类中。
其他编译器,如 GCC 和 LLVM,实现得更直接一些:
在这里,切片会影响你的结果。 (也就是说,毕竟:总是通过引用捕获。)
Visual Studio (Dinkumware?) uses an implementation of
std::exception
that contains internal storage† for the message. (Complete with a non-standard constructor that accepts a string.)Because of this, no virtual dispatch is actually needed to get the error message, it survives any slicing.
A more orthodox implementation would indeed print a generic exception message, because the derived object was sliced off. (Effectively, MS has made
std::exception
andstd::runtime_error
equivalent. There's nothing wrong with this, since the return value ofstd::exception::what
is implementation-defined, but it explains your results.)†Internal storage here is used loosely. It doesn't have an internal buffer, but it has a
const char*
and abool
. Theconst char*
points to the message (the return value ofwhat()
), and thebool
is a flag determining if the buffer should be deleted.It's like this:
You see now that
bad_alloc
works like this:Slicing doesn't affect the message because the message "exists" in the base class.
Other compilers, like GCC and LLVM, implement it a bit more straight-forwardly:
Here, slicing would affect your outcome. (That said, after all this: always catch by reference.)