捕获std :: bad_alloc的策略

问题描述 投票:12回答:6

所以我在开发中使用Qt并且非常喜欢它。 Qt对象的常用设计模式是使用new分配它们。

几乎所有示例(尤其是Qt设计器生成的代码)都绝对不会检查std::bad_alloc异常。由于分配的对象(通常是小部件等)很小,因此这几乎不成问题。毕竟,如果你没有分配20个字节之类的东西,那么你可以做的事情并不多,无法解决问题。

目前,我采用了一种策略,即在try / catch中包装“large”(大小超过一页或两页)分配。如果失败了,我会向用户显示一条消息,几乎任何更小的消息,我只会让应用程序崩溃并发生std::bad_alloc异常。

所以,我想知道这方面的思想是什么?

检查每一个new操作是否是一个好的政策?或者只有我希望有可能失败的?

此外,在处理资源可能受到更多限制的嵌入式环境时,这显然是一个完全不同的故事。我在桌面应用程序的上下文中询问,但也会对涉及其他场景的答案感兴趣。

c++ coding-style new-operator try-catch
6个回答
17
投票

问题不在于“捕获的地方”,而是“捕获异常时该怎么办”。

如果你想检查,而不是用try catch包装你最好使用

    #include <new>
    x = new (std::nothrow) X();
    if (x == NULL) {
        // allocation failed
    }

我通常的做法是

  • 在非交互式程序中,捕获主级别并在那里显示适当的错误消息。
  • 在具有用户交互循环的程序中,也在循环中捕获,以便用户可以关闭某些东西并尝试继续。

在特殊情况下,还有其他地方捕获有意义,但这种情况很少见。


11
投票

尽可能处理异常。如果分配失败,并且您的应用程序无法在没有该内存的情况下继续,为什么还要检查错误?

当有一种有意义的恢复方法时,处理可以处理的错误。如果你无法对错误做任何事情,那就让它传播吧。


6
投票

我通常会在用户发起操作时捕获异常。对于控制台应用程序,这意味着在main中,对于GUI应用程序,我将处理程序放在按钮点击处理程序等位置。

我认为在动作中捕获异常没有多大意义,用户通常希望操作成功或完全失败。


4
投票

这是一个相对较旧的线程,但是当我在2012年进行新的/删除覆盖时,我在搜索“std :: bad_alloc”注意事项时确实出现了这种情况。

我不会把这个概念称为“哦,你无论如何都无能为力”作为一个可行的选择。我个人在我自己的分配中使用上面提到的“if(alloc()){} else {error / handling}”方式。通过这种方式,我可以在他们自己有意义的上下文中正确处理和/或报告每个案例。

现在,其他一些可能的解决方案是:1)覆盖应用程序的新/删除,您可以在其中添加自己的内存处理。

虽然像其他海报一样,特别是对特定环境的了解,但主要选择可能只是关闭应用程序。如果是这种情况,你会希望你的处理程序要么已经预先分配了它所需的内存,要么使用静态内存,所以希望它自己的处理程序不会耗尽。

在这里,您至少可能会弹出一个对话框并说出以下内容:“应用程序内存不足。这是致命错误,现在必须自行终止。应用程序必须以最低系统内存要求运行。发送调试报告到xxxx“。处理程序还可以保存正在进行的任何工作,以适应应用程序。

无论如何,你不会想要将它用于一些重要的事情(警告,业余幽默):航天飞机,心率监测器,肾透析机等。当然,这些东西需要更强大的解决方案,使用故障保险箱,紧急垃圾收集方法,100%测试/调试/模糊测试等

2)与第一个类似,使用您自己的处理程序设置全局“set_new_handler()”以捕获全局范围内的内存不足情况。至少可以像#1中提到的那样处理事情。


1
投票

真正的问题是你真的应该抓住std :: bad_alloc异常吗?在大多数情况下,如果你的内存耗尽,你无论如何都会注定失败,可能会考虑结束你的程序。


0
投票

main()(或Qt中等效的顶级异常处理程序)处理它

原因是std :: bad_alloc要么在耗尽内存空间(32位系统上2或3 GB,64位系统上没有发生)或耗尽交换空间时发生。现代堆分配器未调整为从交换空间运行,因此这将是一个缓慢,嘈杂的死亡 - 您的用户可能会事先杀死您的应用程序,因为它的UI不再响应。在Linux上,默认情况下操作系统内存处理很差,您的应用程序可能会被自动杀死。

所以,你几乎无能为力。承认你有一个错误,看看你是否可以保存用户可能做的任何工作。为了能够这样做,最好尽可能地中止。是的,这可能实际上失去了一些最后的用户输入。但是,这可能是触发OOM情况的非常动作。目标是保存您可以信任的任何数据。

© www.soinside.com 2019 - 2024. All rights reserved.