这取决于您的软件是做什么用的以及您的代码的哪一部分受到影响。
首先要知道,当没有可用页面时 malloc() 可能会失败,如果您的应用程序达到它的限制,那么任何循环都不会工作,但是如果您的系统内存不足,值得一试,但您必须避免任何无限循环.惊喜!如果操作系统临时响应无法分配更多RAM,这完全正常,您可以按自己的方式处理。
这是一个很好的问题
类似的问题是没有捕获信号,当多线程或异步 TCP 服务器的客户端连接中断时,软件会被 SIGPIPE 终止。这是正常的,但会导致您的程序结束,但它不应该。为了防止这种情况,你必须挂钩信号。
在现实世界的例子中(我自己的)。
当 malloc 失败并且只影响我的部分代码时
我曾经在新连接发送数据时使用 malloc() 或 new[],我将接收到的数据存储到缓冲区中,如果 malloc 或 realloc 失败,函数返回 false 并释放缓冲区,连接因错误而断开(内衣)所以在这种情况下,软件会继续运行,但一个连接断开了。我认为这是正确的方法。
当 malloc 必须导致软件中止时
我曾经使用 malloc() 为关键数据腾出空间,例如数组、定义核心的结构,这通常在软件开始时作为 init 部分运行,如果 malloc() 失败,软件必须中止并以错误代码退出,因为所有操作都取决于必须填充数据的表。 (内置文件系统)
当 malloc 能够重试时
我的数据记录器软件属于行业领先的类型(高可用性),如果 malloc() 失败,我会触发 mutex_lock(),这会导致后端软件冻结并尝试重试 malloc 过程 X 秒。如果 malloc() 继续失败,软件开始在所有线程上调用析构函数并执行完全关闭,但此时尝试 malloc() 不成功的线程有两个选项,malloc() 成功并完成堆栈调用和退出最后一个线程或回滚并退出最后一个线程。
每当发生这种情况时,软件也不会退出,请尝试从头开始等等..
也许值得一提..
几年前我也遇到过同样的困境,我的软件中出现了内存泄漏并占用了我所有的 RAM,但为了保存当前状态,我不得不在多次 malloc() 之后将其写出来,解决方案是这发生了,我关闭了所有线程并调用析构函数并保存了数据,但有趣的是当我关闭所有连接并释放套接字时,ssl_ctx,...内存消耗下降到 128KB,经过几天的愉快调试,我想通了SSL_CTX 有内部存储和缓存。所以现在当没有在线连接时,我释放 SSL_CTX 并像魅力一样工作。
总结
所以你可以看到这是一门艺术,你可以用 malloc() 做你想做的事,任何事情都取决于你,没有书也没有标准,如果 malloc() 失败了你应该怎么做。如果有人告诉你应该怎么做,那只是他的意见而已。
我避免无限循环的首选方法
PSEUDO CODE:
var ts = TIME()
var max_seconds = 5
var success = true
WHILE (MALLOC() == FAIL) DO
IF TS + max_seconds < TIME() THEN
success = false
BREAK
END
SLEEP(100ms)
END