C ++ - 避免内存泄漏异常

时间:2014-06-10 20:42:49

标签: c++ pointers memory-management memory-leaks exception-handling

让我们说你有这样的代码:

void myFunction()
{
    myClass * mine = new myClass();
    // body of function
    delete mine;
}

如果在函数体内抛出异常,则永远不会调用delete并导致内存泄漏。除了使用<memory>中的任何托管指针之外,缓解此问题的最佳方法是什么。

4 个答案:

答案 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结构。