如果第一次失败,请重新尝试内存分配
Re-attempt memory allocation should it fail the first time?
我想编写一些对内存不足有抵抗力的代码。 我试图如何去做,如果任何内存分配失败,它将在此时暂停执行,并询问操作员是否可以在重新尝试分配之前尝试释放一些内存(或者如果证明不可能,他们可以选择自己终止程序,这取决于他们)
到目前为止,我的代码似乎很丑陋。 这是进行任何可能扩展数组的 std::vector 操作的块:
while(pointVector.size() == pointVector.capacity){
// will not break past this if the while statement remains true
// ERROR.report() has the power to kill the program if it needs to
try{
pointVector.reserve(pointVector.capacity * 2); // edited
}catch(...){
ERROR.report(Error::Severity::Memory
, __LINE__, __FILE__
, "Failed to allocate enough points"
, pointVector.size(), 0, 0);
}
}
pointVector.push_back(point);
ERROR
对象被专门预先分配了它的所有资源,因此它可以询问操作员而不会引起任何新问题(理论上)。 我的问题是,有没有更好的形式可以采取? 对于这种情况,C++有"重新尝试"的逻辑吗? 或者这几乎是它应该去的样子?
一般来说,不,C++没有内置的方法解决这个问题。内存不足通常不是编程语言通常可以容纳的,因此假设没有所需的内存就无法继续运行,它将失败。由于没有内在的"重试"逻辑,你留下的东西就像你所拥有的一样。抱歉,这里没有特别干净的方法。
根据"你只为你使用的东西付费"的原则,C++不会自己"重复"或"再试一次"。
在这种情况下是否真的值得再试一次,这当然是另一回事......除非您的系统正在运行系统关键型内容,并且内存不足操作是您需要处理的情况的重要组成部分,否则我会说再次尝试可能比救助更糟糕。
您还可以检查错误是否不是std::bad_alloc
[或任何"您无法分配"的名称],因为如果有其他错误,则重试可能毫无意义。
您绝对应该为重复循环的次数设置限制(以防万一ERROR.report()
中存在错误)。
[只要您的项目列表相当小,一次增长 32 个就可以了 - 但我看到的代码几乎与此相同会导致问题,因为一次"仅"增加 32 个到总大小为 32MB,它会导致数据被复制无数次,使应用程序看起来像挂起了, 从而从用户那里得到了错误报告。将其更改为几何增长(每次翻倍)修复了该特定错误]。
除非你有真正特殊的要求,否则如果不满足内存需求,应用程序简单地退出并不是没有道理的:让用户释放内存并再次运行程序。这避免了编写在 99.9% 的情况下不需要的额外代码,在这种情况下,这可能会极大地影响您的性能。
例如,通常push_back
在摊销的恒定时间内运行,但由于容器的大小线性增加,您的"增长 + 推回"组合实际上会线性运行。这种巨大的性能下降将影响所有用户,同时仅为内存不足的一小部分提供好处。
您要查找的函数是std::set_new_handler(new_handler new_p)
它允许您指定在分配由于程序内存不足而即将失败时调用的方法。然后,此方法有机会释放一些内存,以便分配可以成功。如果该方法能够释放一些内存,则应返回 true,否则它必须引发bad_alloc异常或终止程序。(set_new_handler
的文档包含更具体的信息。
使用 set_new_handler
的一个很好的功能是,您不必将每个对 new 的调用包装在 try/catch 块中,以确保您没有耗尽内存。
我认为您最好的方法是在内存池中分配内存并从那里使用内存,这样您就可以完全控制内存,并且可以进行一些清理,例如碎片整理,如果您内存不足。恕我直言,按照您建议的方式进行恢复只会延迟不可避免的事情。
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 尝试摆脱任何堆内存分配
- C++尝试深度复制唯一指针时出现内存访问冲突
- 瓦尔格林德的内存泄漏使用新的
- 当新的故障时,是否有必要留出一些紧急内存?
- 我可以将新的 std::tuple 放入内存映射区域,并在以后读回吗?
- 正在调试 malloc():新内存损坏
- 在我的以下代码中获取 MLE(内存限制错误).尝试解决 ROUND C 2019(问题 A-摆动行走)启动问题
- 当我尝试为结构分配新指针时出现堆栈溢出错误
- 无法避免的libxml2内存泄漏是由于尝试清理时崩溃造成的
- 新的内存必须来自新运营商
- 在插入C STL地图之前,我需要使用新的内存分配内存
- 正在查找新的内存地址?C++
- 如果第一次失败,请重新尝试内存分配
- 我正在尝试在函数中新内存新堆内存,但它给出了错误
- 新的内存池位置
- 为矩阵分配一个新的内存
- 为对象矩阵分配一个新的内存
- [C++]在此代码之前不存在的析构函数中引发的内存错误。尝试创建一个新的动态数组并填充它
- 这是否为shared_ptr分配了新的内存?