首页 > 解决方案 > 局部变量和内存泄漏

问题描述

我正在阅读一些东西,并遇到了这个:

当变量超出范围时调用析构函数

所以我的问题是没有析构函数的变量会发生什么?

举个例子:

class A {
    public:
        A () { }
};

void foo () {
    A a;
}

int main (void) {
    foo();
}

那么在这种情况下是a()a分配用于销毁的内存是否在foo()完成后销毁?

比我有这个例子:

class A {
        std::vector <int> aa;
    public:
        A () : aa(5) { }
};

void foo () {
    A b;
}

int main (void) {
    foo();
}

在这种情况下,分配用于b销毁的内存foo()是否完成?

再澄清一点,我知道这一点:

class A {
    public:
        A () { }
};

相当于

class A {
    public:
        A () { }
        inline ~A() = default;
};

但我的问题是,这个内联破坏foo()是否在完成时调用?

编辑:什么时候inline默认添加了析构函数?

标签: c++memorymemory-leaks

解决方案


如果您不提供析构函数,编译器将为您提供一个。这个析构函数将调用任何成员变量和基类的析构函数。

在某些情况下,您必须编写析构函数以避免泄漏。一种情况是,如果您持有一个指向已分配对象的裸指针,new并且您的对象是“拥有”该指针的最佳候选者。在大多数情况下,当您分配某些东西时,new您认为自己是指针的所有者。

另一种情况是当您获得某种其他类型的资源并需要释放它时。例如,如果您打开一个文件或套接字,您可能需要编写一个自定义析构函数来关闭它。

不过,我对所有这些资源所做的是我创建了一个包装资源的类并有一个关闭它的析构函数。这使问题本地化,因此我必须尽可能少地记住我的大部分代码的资源管理。这是 C++ 中的一个常见习语,被称为RAII,意思是“资源获取即初始化”。

这也是为什么你应该更喜欢make_uniquemake_shared或之类的东西vector来分配内存new。它们为您提供包装内存资源的对象,其析构函数将自动为您释放资源。

要更彻底地回答您对我的答案的评论中的问题...

一旦控制离开它被声明的块,就会调用局部变量的析构函数。举个具体的例子:

void foo () {
    A b;
    {
        A c;
    } // Destructor for c is called here
} // Destructor for b is called here.

推荐阅读