我在假设这个赋值算子的错误时是否正确?

时间:2012-12-24 19:34:57

标签: c++ memory-leaks assignment-operator

理查德·吉拉姆(Richard Gillam)在他的"The Anatomy of the Assignment Operator"中可能发表了一个错误的陈述,他在论文的开头就说了以下内容:

“这个问题的一个正确答案看起来像这样:”

TFoo&TFoo::operator=(const TFoo& that)
{
    if (this != &that)
    {
        TBar* bar1 = 0;
        TBar* bar2 = 0;

        try
        {
            bar1 = new TBar(*that.fBar1);
            bar2 = new TBar(*that.fBar2);
        }
        catch (...)
        {
            delete bar1;
            delete bar2;
            throw;
        }

        TSuperFoo::operator=(that);
        delete fBar1;
        fBar1 = bar1;
        delete fBar2;
        fBar2 = bar2;
    }
    return *this;
}

我认为作者错了,因为如果TSuperFoo::operator=()投掷,bar1bar2会泄漏。

1 个答案:

答案 0 :(得分:1)

如果它看起来像这样就没有内存泄漏:

Tbar* pBar = NULL;

try
{
    pBar = new Tbar();
}
catch (...)
{
    delete pBar;    // clean memory if it was allocated
    throw;          // error was not handled properly, throw it to caller
}

delete pBar;        // no exception was caught, clean the memory

但是在前一个delete之前的情况下,还有另一个可能引发异常的代码,而不是正确的,并且确实存在导致内存泄漏的可能路径,因为在这种情况下分配的内存永远不会被清理干净。

令人遗憾的是,人们编写的代码没有使用这种语言提供的强大功能来避免这种丑陋的内存管理。通常任何具有自动存储持续时间的对象都是足够的,你会发现自己跟随RAII成语,或者在需要动态分配的情况下,那么最好用一些对象包装那些裸指针...智能指针帮助很多。