如何处理malloc返回NULL的情况?使用exit()还是abort()?

7

当malloc()失败时,最好的处理错误的方式是什么?如果它失败了,我想立即退出程序,通常我会使用exit()来做到这一点。但在这种特殊情况下,我不确定是否应该使用exit()。


可能是exit()和abort()之间的区别是什么?的重复问题。 - Donnie
3个回答

14
在库代码中,除非调用者违反了文档化的接口,否则在任何情况下调用exitabort都是绝对不可接受的。如果您正在编写库代码,则应该优雅地处理任何分配失败,释放尝试操作中获取的任何内存或其他资源,并向调用者返回错误条件。然后,调用程序可能会决定exitabort,拒绝需要过多内存的任何命令,释放一些不必要的数据并重试,或适合应用程序的其他操作。
在所有情况下,如果您的应用程序持有尚未与磁盘同步且对用户具有潜在价值的数据,则应尽一切努力确保在分配失败时不丢弃此数据。用户几乎肯定会非常生气。最好将应用程序设计为“保存”功能不需要任何分配,但是如果通常情况下无法这样做,则可以执行频繁的自动保存到临时文件操作或提供一种将内存内容以非标准文件格式(例如需要使用丑陋的XML和ZIP库,每个库都有自己的分配需求)转储到磁盘的方法,而是一种更“原始转储”,您的应用程序可以在下次启动时读取并从中恢复。

如果用户已经消耗了所有可用的系统内存和交换空间,那么他们很难对硬件故障感到生气。这就像责怪应用程序员在电力故障时一样。 - Rag
1
一个强大的系统可以在停电时给你足够的时间来保存数据。即使只是一台笔记本电脑,如果它不是垃圾,你应该有4-10个小时的时间... - R.. GitHub STOP HELPING ICE

5
如果malloc()返回NULL,那么这意味着分配内存失败了。你需要处理这个错误情况。我个人认为因为分配失败就退出整个进程有些过度了,可以用其他方式来解决。

5
我认为这取决于具体应用场景。比如,如果你在写一个编辑器,我会同意你的想法。你至少应该尝试保存打开的文件,可以保存到备份文件中。但是,对于一些需要大量计算的应用程序,如果无法分配足够的内存可能就做不了什么有用的事情了。这种情况下记录错误信息并退出可能是你能做的最好的选择。 - KeithB
1
实际上这取决于应用程序。一个简单的媒体播放器(没有任何音乐下载/购买/播放列表/库功能)在分配失败时退出是完全合理的。但是,一个退出的文字处理器或网络浏览器(可能会在过程中丢失用户的研究论文、部分撰写的博客文章/评论、电子邮件等)会引起用户的极大愤怒。 - R.. GitHub STOP HELPING ICE
此外,现代应用程序何时会出现失败的分配?只有当系统运行失控且系统中没有内存或交换空间时(想象一下内存泄漏的 fork bomb)。因此,在这种情况下尽快崩溃程序并不是一个坏主意。 - Patrick Schlüter
2
我可以想到很多数学应用可能会出现分配失败的情况。例如,如果用户在具有任意精度算术的计算器中键入“print 3!!!!!!!!!!!!!!!!”(“!”表示阶乘)。现在将其不仅仅作为计算器,而是作为数字分析师的研究环境,并享受当某人“只是为了好玩”输入这样的表达式时所收到的仇恨邮件,而没有先保存他们的工作并失去一切。(附言:如果您的应用程序基于GMP,那么正是这种情况会发生...) - R.. GitHub STOP HELPING ICE

1

两者都使用?


这取决于核心文件是否有用。如果没有人打算分析它,那么你可以简单地使用_exit(2)exit(3)

如果程序有时会在本地使用,并且您打算分析生成的任何核心文件,则可以使用abort(3)

您始终可以有选择地使用条件,因此,使用--debug时使用abort(3),而不使用它则使用exit。


1
不建议使用 _exit(),因为这意味着在 atexit() 注册的清理函数将不会运行... - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接