是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
Is it worth making my code less readable for providing exception safety in case of out of memory errors?
我有一个不可复制Item
的游戏,因为它们应该是唯一的:
class Item {
Item() noexcept;
Item(Item&&) noexcept;
Item(Item const&) = delete;
// ...
};
class Creature
能够接收Item
并将其添加到他们的inventory
:
void Creature::receive_item(Item&& item) noexcept {
this->inventory.push_back(std::move(item));
}
void caller_code() {
Creature creature;
Item item;
// ...
creature.receive_item(std::move(item));
}
这种方法看起来很好,很干净,但有一个小问题:如果我的代码的任何部分可以在std::bad_alloc
后恢复,因此捕获了recieve_item()
的push_back()
抛出的一个,那么游戏中的逻辑是未定义的:一个Item
被移动到一个函数,该函数存储了一个失败的函数,所以它只是丢失了。此外,必须删除noexcept
说明符才能实现这种可能性。
因此,我可以以这种方式提供异常安全性(如果我错了,请指出(:
void Creature::receive_item(Item& item) {
this->inventory.resize(this->inventory.size() + 1);
// if it needs to allocate and fails, throws leaving the item untouched
this->inventory.back() = std::move(item);
}
void caller_code() {
Creature creature;
Item item;
// ...
creature.receive_item(item); // no moving
}
但是,现在我们有了新的缺点:
- 调用方代码中缺少
std::move()
掩盖了移动item
的事实; - "resize(+1("部分很丑陋,在代码审查期间可能会被误解。
问题在标题中。即使对于如此奇怪的情况,异常安全也被认为是一个好的设计吗?
问题的答案取决于您是否可以并且想要处理内存分配错误,而不是崩溃。如果你这样做,你将不得不实施措施,而不仅仅是捕捉std::bad_alloc
.大多数现代操作系统都实现了内存过载,这意味着内存分配将成功,但首次访问分配的内存将导致页面错误,这通常会导致崩溃。在将指针返回给调用方之前,您必须显式错误分配的内存分配页面以检测内存不足情况。
关于代码修改,您不必修改对push_back
的调用:
this->inventory.push_back(std::move(item));
如果push_back
(或任何其他潜在的重新分配方法(需要分配新的缓冲区,它将在将新项移动到向量之前执行此操作。显然,这是因为向量中没有空间可以将新元素移动到。当重新分配缓冲区并将所有现有元素移动/复制到新缓冲区时,新元素将作为最后一步移动。
换句话说,如果抛出push_back
,您可以确定新项目未被移动。如果它没有抛出并正常返回,则项目将从中移出。
相关文章:
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 如何消除ROS打开CV中的内存不足错误?
- 在 Linux 上C++的无限循环中捕获内存不足的错误 bad_alloc()
- 访问违规可以是一个伪装的内存不足错误吗
- 为什么我在一段时间后不断出现MySQL客户端内存不足错误.
- C++:光线追踪器导致内存不足错误 - 由于反复调用"new"?
- 内存不足错误Opencv/c++
- 收到 OpenCV 错误:运行 OpenCV 示例程序时内存不足:"stitching_detailed.cpp"
- 错误:arma::memory::acquire():犰狳的内存不足
- mlpack:内存不足错误
- Opencv错误:当我使用screen()时内存不足(无法分配)
- OpenCV错误:内存不足
- 内核中的"while"/"for"循环导致 CUDA 内存不足错误?
- 内存不足错误
- 如何修复内存不足错误(openCV)
- 将ID3D11Texture2D复制到字节数组,导致内存不足错误c++
- GLUT:致命错误:内存不足
- MPI错误:内存不足-有哪些解决方案选项
- 将巨大的字符串从本机传递到 java - 内存不足错误
- 内存不足错误在c++ /MFC应用程序