“这个问题的一个正确答案看起来像这样:”
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=()
投掷,bar1
和bar2
会泄漏。
答案 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成语,或者在需要动态分配的情况下,那么最好用一些对象包装那些裸指针...智能指针帮助很多。