C ++局部变量和内存泄漏

时间:2019-03-27 21:45:35

标签: c++ memory memory-leaks

我正在阅读一些内容,并偶然发现:

  

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

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

例如:

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析构函数作为默认值?

2 个答案:

答案 0 :(得分:2)

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

在某些情况下,必须编写析构函数以避免泄漏。一种情况是,如果您持有指向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.

答案 1 :(得分:1)

来自the standard

  

如果类没有用户声明的析构函数,则将析构函数隐式声明为默认的([dcl.fct.def])。隐式声明的析构函数是其类的inline public成员。

换句话说,

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

等同于

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

关于你的问题

  

但是我的问题是,foo()完成后是否会调用此内联销毁?

答案是肯定的。但是,即使对于用户定义的析构函数也是如此。