linux上c++内存分配new (nothrow)失败时该怎么做
what to do upon failure of memory allocation new (nothrow) in c++ on linux
在no-exception上下文中,我看到几个帖子说
Thing* t = new(std::nothrow) Thing; // returns NULL on failure
if (!t) {
// allocation failure
}
。
如何检查内存分配失败与新的操作符?
如何找出返回值,如果我的c++"新"内存分配失败?
我相信这是他们从c++标准中得到的声明,如引用:
如果分配函数声明为非抛出类型异常规范,它返回null以指示失败否则分配存储空间和非空指针。
然而,由Herb Sutterhttp://www.gotw.ca/publications/mill16.htm
linux会过度使用内存,这是不符合c++标准的。也就是说,检查null与Linux系统无关。"new"的成功与否取决于进程是否被linux杀死。
那么我们能做什么呢?似乎没有办法检查失败。
[UPDATE] about linux overcommit: overcommit_memory
0 -默认设置。内核执行启发式内存通过估计可用内存量和明显无效的失败请求。不幸的是,自内存分配使用启发式算法,而不是精确算法,这种设置有时允许系统上的可用内存被占用过载。
Linux默认不复用。真正的解决方案是不要这样配置它。
鱼和熊掌不可兼得。如果您在默认状态下使用linux(不过度提交),那么检测内存分配错误是没有问题的。如果你将它配置为过度提交,那么你需要设计你的程序,使它不会耗尽内存(即确保有比你的程序将尝试分配更多的可用内存)或重新构建你的程序,使它在失败之前终止,从而产生不必要的后果(例如,不销毁对象和保存状态到文件)。 然而…如果您坚持要将系统配置为过度提交,那么Herb在该链接中暗示了解决方案。
本质上,有必要重新组织你的程序,以便所有的动态内存分配都是预先完成的。
p = new (nothrow) Thing;
if (p != NULL)
touch(p);
else
terminate_with_prejudice()
其中touch()
确保在linux下提交内存分配(草本的页面描述了如何做到这一点)。
或者,用于抛出new;
try
{
p = new Thing;
touch(p);
}
catch (...)
{
terminate_with_prejudice()
}
如果发生故障,则程序将在任何系统上异常终止。如果在启动前完成此操作,则不会造成任何损坏(除非程序未启动)。
区别在于故障在不同系统上的发生方式。对于这两种形式,linux系统将始终调用touch()
,并且程序将在出现故障时异常执行。在非linux系统上,terminate_with_prejudice()
将在故障时被调用。无论哪种方式,程序都将停止执行。
异常的捕获是可选的,但我这样做是为了使两个代码示例相等(至少,在任何选定的系统上)。
这里的问题(没有双关语的意思)是,重新构建整个程序以避免在启动后向主机系统请求内存是很重要的。不这样做将意味着以同样的方式终止,但不能始终保证程序可以执行任何必要的清理。
- 如果没有malloc,链表实现将失败
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- gcc和c++17的过载解析失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 从父数组测试用例构造二叉树失败
- LibGit2 SSH身份验证失败
- 如何让LLDB在成功时退出,在失败时等待
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- 生成MRPT库时cmake配置失败
- 如何使用new(std::nothrow)使构造函数失败
- linux上c++内存分配new (nothrow)失败时该怎么做