我想编写一些有点内存不足的代码。我是如何试图去做的,如果任何内存分配失败,它将暂停执行,并询问操作员是否可以在重新尝试分配之前尝试释放一些内存(或者它应该被证明是不可能的,它们是可以选择自己终止程序,这取决于他们)
到目前为止我的代码看起来很丑陋。这是进行任何可能扩展数组的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 ++是否为这种情况“重新尝试”逻辑?或者这是怎么回事?
答案 0 :(得分:3)
通常,不,C ++没有内置的方法。耗尽内存不是编程语言通常可以容纳的内容,因此假设在没有所需内存的情况下无法继续执行功能,它将失败。既然没有内在的“重试”逻辑,那么你就会得到类似于你所拥有的东西。对不起,这里没有特别干净的方法。
答案 1 :(得分:2)
根据“你只为你使用的东西买单”的原则,C ++本身不会“重复”或“再试一次”。
在这种情况下是否真的值得再次尝试这当然是另一回事......除非你有一个系统,你运行一些系统关键的东西,低内存操作是你的情况的很大一部分需要处理,我会说再次尝试可能不会畏惧。
你也可以检查错误是否是std::bad_alloc
以外的东西[或者你不能分配的任何东西],因为如果有其他错误则重试可能是毫无意义的。
您应该为重复循环的次数设置一个限制(以防ERROR.report()
中存在错误)。
[只要您的项目列表相当小,一次只能增加32个 - 但我看到的代码几乎与此相同导致问题,因为通过一次只增加32个到总大小32MB,它导致数据被复制数十亿次,使应用程序看起来像挂起,从而得到了用户的错误报告。将其更改为几何增长(每次加倍)修复了该特定错误]。
答案 2 :(得分:2)
除非您有真正的特殊要求,否则您不会在您的问题中讨论,如果不满足内存需求,应用程序只需退出就不是不合理的:让用户释放内存并再次运行程序。这样可以避免编写99.9%的情况下不需要的额外代码,在这种情况下,可以 影响您的性能。
例如,通常push_back
以摊销的常量时间运行,但由于线性增加容器的大小,您的“增长+推回”组合实际上将在线性时间运行。这种巨大的性能下降会影响所有用户,同时只为那些经历内存不足的小部分提供好处。
答案 3 :(得分:1)
您正在寻找的功能是std::set_new_handler(new_handler new_p)
它允许您指定在分配即将失败时调用的方法,因为程序内存不足。然后,此方法有机会释放一些内存,以便分配成功。如果该方法能够释放一些内存,则它应该返回true,否则它必须抛出bad_alloc异常或终止程序。 (set_new_handler
的文档包含更具体的信息。)
使用set_new_handler
的一个很好的功能是,您不必在try / catch块中将每次调用都包装到new中,以确保没有内存不足。
答案 4 :(得分:0)
我认为你最好的方法是在内存池中分配内存并从那里使用内存,这样你就可以完全控制内存,如果内存不足,可以像碎片整理一样进行清理。按照你提出的方式进行恢复,恕我直言,只是推迟了不可避免的事情。