我在代码中使用 STL 容器(使用 Visual Studio 2010 在 C++ 中开发)
我以前从未使用过 STL 容器的异常处理。由于 STL 容器抛出 bad_alloc
异常,我计划在下面显示的示例代码 中使用 like。假设 function()
在内存不足的情况下被调用。
现在,我不确定它是否是完整的证明代码,或者我是否需要进行任何额外的清理事件。
class MyClass
{
std::vector<int>* integer_vector;
public:
MyClass()
{
std::string message;
message += "my message"; // bad_alloc could be thrown from here
integer_vector = new std::vector<int>; // bad_alloc could be thrown from here
}
};
void function()
{
try
{
MyClass* myclass_ptr;
myclass_ptr = new (std::nothrow) MyClass;
if (myclass_ptr==NULL)
{
// ANY CLEANUP NEEDED HERE ?
return;
}
std::map<int, char> myintcharmap; // bad_alloc could be thrown from here
}
catch(...)
{
// ANY CLEANUP NEEDED HERE ?
return;
}
}
请有人看看并提供帮助。
最佳答案
您显示的代码中有两个主要的潜在漏洞。这两者都可以说源于使用原始指针。您应该更喜欢使用 std::unique_ptr
(如果您有 C++11)或其他类似的“智能”指针来指示所有权,以及一般的异常安全性。现代指南是避免几乎所有使用 new
或 delete
;当它们无法避免时,它们需要配对。请注意,您的代码有两次调用 new
但没有调用 delete
。
在 function
内部,核心问题是您可以完全分配 myclass_ptr
“拥有”的数据,在以后的分配中导致异常,然后无法清理它因为 myclass_ptr
不再在范围内。
假设您修复了它,因此如果在创建后发生异常,它会清除 MyClass
实例。您的代码仍然会泄漏,因为在 MyClass
中目前存在与 integer_vector
类似的问题。虽然您可以遵循三原则并编写一个析构函数来处理这种情况,但在这里使用智能指针可能更容易。
异常处理是一个更大、更自以为是的话题。我将总结一下,捕获异常并压缩它们通常是不好的(通常这只在需要特定类型稳定性的程序的外循环中才是合法的)。在如此狭窄的范围内捕获异常以致于您不知道如何处理它们通常也很糟糕。 (例如,function
将如何决定是再试一次、放弃还是使用另一种方法?它的调用者,或者链上更远的调用者,可能有更多的信息并且处于更好的位置来处理这个。)
关于c++ - 在低内存情况下使用具有异常处理的 STL 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23946064/