gpt4 book ai didi

c++ - 在 Linux 上的 C++ 中内存分配新(nothrow)失败时该怎么办

转载 作者:太空狗 更新时间:2023-10-29 12:29:39 26 4
gpt4 key购买 nike

在无异常(exception)的情况下,我看到几个帖子说

Thing* t = new(std::nothrow) Thing; // returns NULL on failure
if (!t) {
// allocation failure
}

例如

How to check memory allocation failures with new operator?

How to find out the return value if my C++ “new” memory allocation failure?

我相信这是他们从 C++ 标准中得到的声明,如引用的那样:

If the allocation function is declared with a non-throwing exception-specification , it returns null to indicate failure to allocate storage and a non-null pointer otherwise.

然而,Herb Sutter http://www.gotw.ca/publications/mill16.htm

linux会过度使用内存,这不符合c++标准。即,检查 null 与 linux 系统无关。"new"要么成功要么失败,进程被 linux 杀死。

那我们能做什么呢?似乎没有办法检查失败。

[更新] 关于 linux 过度使用:overcommit_memory

0 — The default setting. The kernel performs heuristic memory overcommit handling by estimating the amount of memory available and failing requests that are blatantly invalid. Unfortunately, since memory is allocated using a heuristic rather than a precise algorithm, this setting can sometimes allow available memory on the system to be overloaded.

最佳答案

默认情况下,Linux 不会过度使用。真正的解决方案不是像它那样配置它。

你不能既吃蛋糕又吃蛋糕。如果您在默认状态下使用 linux(未过度使用),则检测内存分配错误没有问题。如果您将其配置为过度使用,那么您需要设计您的程序以使其不会耗尽内存(即确保可用内存多于您的程序将尝试分配的内存)或重新设计您的程序以使其在失败之前终止产生不良后果(例如,不破坏对象并将状态保存到文件)。

但是......如果您坚持将系统配置为过度使用,那么 Herb 会在该链接中提供解决方案的提示。

本质上,有必要重新组织您的程序,以便所有动态内存分配都预先完成并触及。

  p = new (nothrow) Thing;
if (p != NULL)
touch(p);
else
terminate_with_prejudice()

其中 touch() 确保内存分配在 linux 下提交(Herbs 的页面描述了如何做到这一点)。

或者,用于抛出新的;

  try
{
p = new Thing;
touch(p);
}
catch (...)
{
terminate_with_prejudice()
}

如果发生故障,则程序将在任何系统上异常终止。如果这是在启动之前完成的,则不会造成任何损害(除非程序未启动暗示)。

不同之处在于故障在不同系统上的发生方式。对于这两种形式,linux 系统总是会调用touch(),程序会在失败时异常执行。在非 Linux 系统上,terminate_with_prejudice() 将在失败时调用。无论哪种方式,程序都会停止执行。

异常的捕获是可选的,但我这样做是为了使两个代码示例等效(至少在任何选定的系统上)。

这里的问题(没有双关语意)是重新构建整个程序以避免在启动后向主机系统请求内存是非常重要的。不这样做将意味着以相同的方式终止,但不能始终如一地保证程序可以进行任何必要的清理。

关于c++ - 在 Linux 上的 C++ 中内存分配新(nothrow)失败时该怎么办,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31539157/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com