您多久检查一次C++;新指令? 我刚刚开始阅读有效C++,并谈到作者谈论new new。< /p>
这本书很好地解释了如何(以不同的优雅程度)捕获std::bad_alloc异常,如果内存不足,new操作符会引发该异常您多久检查一次C++;新指令? 我刚刚开始阅读有效C++,并谈到作者谈论new new。< /p>,c++,exception,C++,Exception,这本书很好地解释了如何(以不同的优雅程度)捕获std::bad_alloc异常,如果内存不足,new操作符会引发该异常 我的问题是:如果没有足够的内存来实例化一个对象,您多久检查一次这种情况?为什么?值得这么做吗?如果您必须为路径缓冲区分配内存,而您知道它只有几个字节,那么可能不值得这么做 但是,当您必须为较大的对象(如图像或文件)分配内存时,您肯定应该进行检查。我认为最重要的是始终意识到内存可能会耗尽。然后决定你是否在乎。考虑尝试和抓住每一个分配--这是一个很大的麻烦。与能够优雅地处理无内存情
我的问题是:如果没有足够的内存来实例化一个对象,您多久检查一次这种情况?为什么?值得这么做吗?如果您必须为路径缓冲区分配内存,而您知道它只有几个字节,那么可能不值得这么做
但是,当您必须为较大的对象(如图像或文件)分配内存时,您肯定应该进行检查。我认为最重要的是始终意识到内存可能会耗尽。然后决定你是否在乎。考虑尝试和抓住每一个分配--这是一个很大的麻烦。与能够优雅地处理无内存情况的应用程序相比,在提高生产率和简化代码之间进行选择。我认为在正确的环境下,这两种收益都是非常有价值的,所以请仔细选择 是的,您可以通过定义一个模板基类来简化您的工作,该模板基类提供一个自定义运算符new和运算符delete,并设置一个新的处理程序。然后您可以使用该模式从这个基类派生。然后,您的派生类将优雅地处理错误的分配,但您仍然需要记住在您创建的每个新类上从该基类派生。通常,您可能会以多重继承结束,这可能会带来自身的复杂性。无论您如何处理错误的分配,您的代码都不会像您不费事那样简单
这个问题从来没有一个答案。这是您必须做出的选择,取决于始终的上下文。问题是,当内存耗尽时,除了写入崩溃转储并退出程序之外,您通常没有什么可以做的。因此,检查程序中的每一个新项都是无用的
这种情况的一个例外是,当您为加载文件分配内存时,在这种情况下,您只需通知用户没有足够的内存用于请求的操作。在使用虚拟内存的系统中,malloc()不会返回NULL,new不会返回std::bad\u alloc;它们将返回一个虚拟地址。当您写入此地址指向的内存区域时,系统将尝试将虚拟地址映射到物理地址。如果没有更多可用内存,则会出现页面错误
因此,当你在没有MMU的嵌入式系统上时,你会发现std::bad_alloc,并希望你能做些什么来释放一些内存。永远不要。我一直认为默认行为(有一个std::bad_alloc异常,它没有被处理,因此程序会以错误消息终止)对于我所使用的应用程序来说是好的。不处理异常会使您的程序崩溃,您收到的支持请求将介于“不工作”之间,“随机崩溃”和“我失去了那天所有的工作”。如果你认为这没关系,那就不值得这么麻烦了 你至少可以告诉用户,他实际上已经耗尽了内存,至少可以给他(或支持)一个线索,说明应用程序为什么会随机崩溃 此外,您可以尝试保留结果,例如将结果保存到恢复文件中。不过,在遇到问题之前,这可能更容易做到 如果你能给出一条错误消息,比如“你无法插入此图像,因为你的内存不足”,那就太棒了。你会继续工作,就像什么都没发生一样。但是,这意味着用户命令背后的所有代码都必须是事务性的,并且给出一个错误消息
因此,确定随机耗尽内存的成本。在此基础上,评估哪种“保护级别”“您需要向您的用户提供 我认为这在很大程度上取决于您编写的应用程序的类型。如果我写的东西不影响系统的全局稳定性,比如说一个游戏或一个电影播放器,我不会检查这个例外。我的应用程序将调用
std::terminate
,我可以将它记录在某个地方,或者我的内核将首先杀死我的程序,为其他程序腾出空间
如果我编写一个程序,其稳定性直接对应于它所运行的系统之一,比如视频驱动程序或init系统,我会一直检查内存异常(可能在函数中包装分配),并在分配失败的情况下从预分配的池中获取一些内存
我认为这一切都取决于比例。如果一个稳定得惊人的电影播放器因为你的攻击性检查而开始放慢播放速度,你会从中得到什么
顺便说一句,有人回答说,当某些系统的内存不足时,malloc不会返回0。没错,但正如malloc的主页所指出的(特定于linux)
如果Linux是在不太希望突然丢失一些随机选取的进程的情况下使用的,而且内核版本足够新,那么可以使用如下命令关闭这种过度提交行为:$echo 2>/proc/sys/vm/overmit\u memory
另请参阅内核文档目录,文件vm/overmit accounting和sysctl/vm.txt
当我能回答这个问题时,我捕捉到异常: 一旦捕捉到异常,您将如何处理它 大多数时候,我的回答是,“我不知道。也许我的来电者知道。”所以我没有发现异常。让那些更了解情况的人知道 当你捕捉到一个异常并让你的函数继续运行时,你对你的程序说,“没关系,这里一切都很好。”当你这么说的时候,天哪,一切都有可能