0

如果我有一个类A并且某些主体使用我的代码创建一个对象,然后在没有周围的情况下A调用,内存会泄漏吗?在 valgrind 的报告中可能丢失并且仍然可以访问是否表明内存泄漏?如果没有,如何避免它们?更何况,构造函数也不安全吧?我必须在这里使用智能指针替换原始指针吗?还有一种叫做“复制和交换”的策略,什么时候使用它?由于 operator new 可能会抛出异常,所以当我想在堆上动态分配内存时,我有点困惑。DoSth()try-catchAAnimal*

代码

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;
}

Valgrind 报告

==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
4

1 回答 1

-1

Valgrind 的报告显示了潜在的内存泄漏,因为您让异常冒泡到应用程序级别,这会杀死应用程序。然后释放资源。

不过,有几点需要注意:

1)如果一个函数有可能抛出异常,你应该在它到达应用程序级别之前处理该异常(在那个级别,异常会杀死你的应用程序 - 异常的想法是允许你优雅地处理错误)。

2)为什么要Animal在堆上分配?在此设置中,它可以很容易地分配到堆栈上,在这种情况下,您也不会在 Valgrind 中显示潜在的泄漏。

如果您担心new抛出异常(实际上,这通常仅在您用完内存分配时才会发生......所以不经常发生),您需要在单独的函数中定义初始化(即使智能指针也不会为你避免这个问题),或者在构造函数中有一个 try-catch 块,或者不要放在Animal堆上。

于 2013-09-16T14:13:43.760 回答