C++ 关于异常安全和内存泄漏的一些问题
如果我有一个类C++ 关于异常安全和内存泄漏的一些问题,c++,exception,memory-leaks,valgrind,C++,Exception,Memory Leaks,Valgrind,如果我有一个类a,某个主体使用我的代码创建a的对象,然后调用DoSth(),而不调用try catch,内存会泄漏吗?valgrind报告中可能丢失且仍可访问是否表明内存泄漏?如果没有,如何避免?更重要的是,A的构造函数是不安全的,对吗?我是否必须使用智能指针来替换原始指针Animal*?还有一种叫做“复制和交换”的策略,何时使用?因为new操作符可能会抛出异常,所以当我想在堆上动态分配内存时,我不太清楚该怎么做 代码 瓦尔格林报告 Valgrind的报告显示了一个潜在的内存泄漏,因为您让异常冒
a
,某个主体使用我的代码创建a
的对象,然后调用DoSth()
,而不调用try catch
,内存会泄漏吗?valgrind报告中可能丢失且仍可访问是否表明内存泄漏?如果没有,如何避免?更重要的是,A
的构造函数是不安全的,对吗?我是否必须使用智能指针来替换原始指针Animal*
?还有一种叫做“复制和交换”的策略,何时使用?因为new操作符可能会抛出异常,所以当我想在堆上动态分配内存时,我不太清楚该怎么做
代码
瓦尔格林报告
Valgrind的报告显示了一个潜在的内存泄漏,因为您让异常冒泡到应用程序级别,这会杀死应用程序。然后释放资源 但是,需要注意的是: 1) 如果函数可能引发异常,则应在异常到达应用程序级别之前处理该异常(在该级别,异常将终止应用程序-异常的概念是允许您优雅地处理错误) 2) 为什么要在堆上分配
动物
?在这种设置中,它可以很容易地分配到堆栈上,在这种情况下,Valgrind中也不会显示潜在的泄漏
如果您担心
new
抛出异常(实际上,这通常只在内存不足时发生……所以不太常见),则需要在单独的函数中定义初始化(即使是智能指针也无法避免该问题),或者在构造函数中有一个try-catch块,或者不要将Animal
放在堆上。在这种情况下:否,因为“a”是堆栈分配的,当异常导致堆栈展开时,它将被释放(调用其析构函数)。如果在堆上分配了“a”(或者在“DoSth()”中分配内存,但由于异常而没有释放内存),则可能会发生泄漏。为什么要在堆上分配Animal
对象?@ZacHowland这只是一个模拟具有指针数据成员的类的示例。这个类可能会在运行时抛出异常。谢谢!扎克·霍兰德。在阅读了“高效C++”中关于异常安全的章节后,我开始关注我的代码。现在,我感觉好多了。。。
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