处理函数返回的异常 std::string

Handling exception in function returning std::string

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

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

因为任何 stl 构造函数都可以抛出 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 块仍然不安全。

我只想做这个函数的异常证明。

虽然,(我认为)它没有被标准所保证运行,但大多数(也许是所有)std::string 实现不会为 empty/short 字符串分配内存(如@BoBTFish 所述)。所以你的解决方案就是"exception proof",因为它得到了。我只是建议,实际上 return 一个默认构造的字符串而不是 "".

但是,您应该问自己的基本问题是 bad_alloc 是否符合您的预期,因为您可能正在尝试构造一个非常大的字符串,或者如果它实际上表明您的系统完全 运行 内存不足:

如果分配失败,因为您试图创建一个包含几百万个字符的字符串,那么构建一个 shorter/empty 错误字符串可能不会抛出另一个异常,这可以看作是正确的错误处理形式。

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

尽量遵循这条准则:只有在可以处理异常的根本原因时才捕获异常。抑制异常并没有解决异常暴露的底层问题。

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

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

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

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

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

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

I just want to make this function exception proof.

不可能创建std::string并保证不抛出bad_alloc