如果我有一个类A
并且某个正文使用我的代码来创建A
的对象,那么在没有DoSth()
的情况下调用try-catch
,内存会泄漏吗?在valgrind的报告中可能丢失并仍然可以达到内存泄漏?如果没有,如何避免它们?更重要的是,A
的构造函数不安全吗?我是否必须使用智能指针来替换原始指针Animal*
?还有一个名为“copy-and-swap”的策略何时使用?由于new new可能会抛出异常,因此当我想在堆上动态分配内存时,我很困惑该怎么做。
class A
{
public:
A(const string& petname, int petage)
:pet_(new Animal(petname, petage))
{
}
~A()
{
delete pet_;
}
void DoSth()
{
// do sth...
throw;
}
private:
Animal* pet_;
};
int main(int argc, char const *argv[])
{
A a("Kitty", 3);
a.DoSth();
return 0;
}
==2799== LEAK SUMMARY:
==2799== definitely lost: 0 bytes in 0 blocks
==2799== indirectly lost: 0 bytes in 0 blocks
==2799== possibly lost: 30 bytes in 1 blocks
==2799== still reachable: 16 bytes in 1 blocks
==2799== suppressed: 0 bytes in 0 blocks
答案 0 :(得分:-1)
Valgrind的报告显示了潜在的内存泄漏,因为您将异常泡沫升级到应用程序级别,从而导致应用程序崩溃。然后释放资源。
然而,有些事情需要注意:
1)如果某个函数有可能抛出异常,你应该在它到达应用程序级别之前处理该异常(在该级别,该异常将终止你的应用程序 - 异常的想法是允许你处理错误正常)。
2)为什么要在堆上分配Animal
?它可以很容易地在这个设置中分配到堆栈中,在这种情况下,你也不会在Valgrind中显示潜在的泄漏。
如果您担心new
抛出异常(实际上,这通常只会在内存耗尽时才会发生...所以不经常发生),您需要在a中定义初始化单独的函数(即使是智能指针也不能避免这个问题),或者在构造函数中有一个try-catch块,或者不要将Animal
放在堆上。