如何处理 std::vector 的错误?

Posted

技术标签:

【中文标题】如何处理 std::vector 的错误?【英文标题】:How to handle errors with std::vector? 【发布时间】:2020-12-18 09:38:24 【问题描述】:

std::vector 分配的内存可能会失败,但是构造函数不能返回任何东西,我们是否应该在每次声明std::vector 时使用trycatch

我知道这个问题可能已经回答了,但我没有找到任何东西,请评论链接。

【问题讨论】:

如果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 的错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理与派生类不兼容的基类方法?

处理 Mongoose 验证错误——在哪里以及如何处理?

如何处理错误?

处理包/模块中的错误时如何处理Python异常

如何处理 ValueError:分类指标无法处理多标签指标和多类目标错误的混合

如何处理 react/redux 中的请求错误?