如何处理 std::vector 的错误?
Posted
技术标签:
【中文标题】如何处理 std::vector 的错误?【英文标题】:How to handle errors with std::vector? 【发布时间】:2020-12-18 09:38:24 【问题描述】:std::vector
分配的内存可能会失败,但是构造函数不能返回任何东西,我们是否应该在每次声明std::vector
时使用try
和catch
?
我知道这个问题可能已经回答了,但我没有找到任何东西,请评论链接。
【问题讨论】:
如果std::vector
抛出这样的异常,您是否希望能够做任何有意义的事情?
关于异常的事情是,如果你没有在任何地方捕获它们,它们最终会终止你的程序。因此,用异常处理程序乱扔代码库会注意到但中止问题是不必要的冗长。
@FrançoisAndrieux 我可以想象这样一种情况,其中一个操作需要制作一个 DWORD 向量来表示 big 位图中的像素。如果由于 BAD_ALLOC 导致构造失败,那么我可以建议用户减小位图的大小。
您可以根据应用程序的设计在外部范围内处理问题。
@rsjaffe — 标记一个可以抛出异常的函数noexcept
通常是个坏主意。调用链中较高的函数可能需要进行清理,并且短路正常的堆栈展开可以防止这种情况发生。中止应用程序的决定是应用程序设计的问题,而不是本地编码。
【参考方案1】:
是的,std::vector
中使用的默认分配器可能会引发 严重 条件,例如“内存不足”。未处理的异常会自动调用std::terminate()
,它本身对于这些情况来说是一个足够好的处理程序,因为它们通常不应该发生(在具有虚拟内存的现代系统上,std::bad_alloc
很少是内存不足的标志,而是一个标志程序中的错误,例如尝试分配负数)。
所以“什么都不做”是处理可能抛出的std::vector
的一种很好的方法。
在 Linux 上你会得到terminate called after throwing an instance of 'std::bad_alloc', what(): std::bad_alloc, Aborted (core dumped)
。
不幸的是,有些平台(例如 Windows)std::terminate()
不打印任何内容。
为了获得最佳可移植性,您可以在全局范围内使用catch
all std
异常来在退出之前打印一些有意义的错误消息。例如:
int main()
try
// program code ...
catch (std::exception const& e)
std::cerr << "Exception: " << e.what() << std::endl;
exit(1);
也不要忘记以类似的方式处理任何其他线程(如果有)。
在任何情况下,每个std::vector
实例单独的try
-catch
将是矫枉过正。
【讨论】:
以上是关于如何处理 std::vector 的错误?的主要内容,如果未能解决你的问题,请参考以下文章