1

如何处理std::bad_alloc此函数中的异常:

std::string GetString()
{
    std::string str;
    return str;
}

由于任何 stl 构造函数都可以 throw bad_alloc,我们必须这样做:

std::string GetString()
{
    try
    {
        std::string str;
        return str;
    }
    catch(std::bad_alloc&)
    {
        return ""; // Constructs temporary std::string and returns. Could throw !
    }
}

再次catch阻止仍然不安全。

我只是想让这个功能异常证明。

4

4 回答 4

2

尽管(我认为)标准不能保证,但大多数(可能是所有)std::string实现不会为空/短字符串分配内存(如@BoBTFish 所述)。因此,您的解决方案是“异常证明”,因为它得到了。我只是建议,实际上返回一个默认构造的字符串而不是"".

但是,您应该问自己的基本问题是,是否bad_alloc是您所期望的,因为您可能正在尝试构建一个非常大的字符串,或者如果它实际上表明您的系统完全耗尽了内存:

如果分配失败,因为您尝试创建一个包含几百万个字符的字符串,那么构造一个较短/空的错误字符串可能不会引发另一个异常,这可以被视为错误处理的正确形式。

如果它失败了,因为你的程序/系统完全耗尽内存,你不能在本地处理它(例如你不能释放任何其他内存),因此你可能也不应该尝试隐藏那个错误,因为它肯定会再次出现不久之后。因此,虽然返回一个空字符串或短字符串可能仍然有效,但我认为没有理由首先在您的函数中捕获该异常。

于 2015-03-13T12:00:05.093 回答
1

尝试遵循以下准则:仅在能够处理其根本原因时才捕获异常。抑制异常并不能解决异常暴露的根本问题。

回答你的问题;对于抛出 std::bad_alloc 的原因,您的函数无能为力。调用堆栈更高的另一个函数可能能够做一些事情,如果你抑制异常,你就不可能做到这一点。

于 2015-03-13T12:45:39.747 回答
0

作为一般规则,除非您知道如何处理异常,否则永远不要捕获异常。

此外,由于未捕获的异常而崩溃的程序比尝试解决异常后崩溃的程序更容易调试

在您展示的情况下,如果创建一个空字符串是一个原因,bad_alloc那么返回""也可能会导致另一个bad_alloc(隐式创建另一个空字符串)。

在极少数情况下您可以解决 a bad_alloc:例如,如果您知道要缓存大量数据,则可以释放缓存的数据并重试分配。

于 2015-03-13T12:57:23.993 回答
0

永远不要捕获与函数实现在语义上不相关的异常。否则,您将最终捕获std::exception每个函数,这显然是无稽之谈。

我只是想让这个功能异常证明。

不可能创建 astd::string并保证不 throw bad_alloc

于 2015-03-13T13:29:58.830 回答