让我们说你有这样的代码:
void myFunction()
{
myClass * mine = new myClass();
// body of function
delete mine;
}
如果在函数体内抛出异常,则永远不会调用delete
并导致内存泄漏。除了使用<memory>
中的任何托管指针之外,缓解此问题的最佳方法是什么。
答案 0 :(得分:11)
使用RAII。有很多方法可以做到这一点,最好的方法是使用久经考验的解决方案,例如std::unique_ptr<myClass>
或boost::scoped_ptr<myClass>
等智能指针。
如果您想自己动手实施RAII解决方案,可以采用范围保护的形式:
struct guard
{
myClass* ptr;
guard(myClass* p) : ptr(p) {}
~guard() { delete ptr; }
guard(const guard&) = delete;
guard& operator=(const guard&) = delete;
};
请注意,RAII要求代码在某个级别的try块中。
答案 1 :(得分:2)
使用std::auto_ptr
或(使用C ++ 11)std::unique_ptr
可以轻松避免此类内存泄漏:
#include <memory>
void myFunction()
{
std::unique_ptr<myClass> mine(new myClass());
// Use mine as before, mine->foo() or *mine is totally valid
// The instance of myClass is deleted as soon as the unique_ptr goes out of scope
// body of function
}
答案 2 :(得分:0)
可以使用没有智能指针来管理它的方法,但不建议这样做:
void myFunction()
{
myClass * mine = 0;
try {
mine = new myClass();
// body of function
}
catch(...) {
delete mine;
throw;
}
delete mine;
}
同样,这种方法更容易出错(代码重复等),RAII是之前回答的首选。
答案 3 :(得分:0)
您的第一个偏好应该是不要使用new
。你的剥离示例中没有任何内容表明堆栈分配会失败:
void myFunction()
{
myClass mine;
// body of function
}
如果你确实需要在堆上进行分配,那么更喜欢使用RAII包装器(优先使用标准库中的包装器而不是自定义包装器),或尝试使用/ catch结构。