何时对堆中的对象调用 C++ 析构函数?

nnr*_*les 1 c++ pointers memory-leaks vector

假设一个类及其用法

#include <vector>
class B
{
 public:
     B() {temp = 0;}; // implemented 
    ~B() {} ; // implmented 
 private : 
      int temp; 
      // it holds a std::bitset , a std::vector.. It is quite large in size.
};

class A 
{
    private:
    std::vector<B*> * _data ; 
    public: 
    A()
    {
       _data = new std::vector<B*>(0); 
    }
    ~A()
     {
         for(unsigned int idx_ = 0; idx_ < _data->size(); ++idx_)
              delete _data->at(idx_);
         delete _data ; 
     }
     void addB()
     {
          B * temp = new B();
          _data->push_back(temp);
     }
}



int main()
{
   A temp; 
   temp.addB(); 
    // Do something 
}
Run Code Online (Sandbox Code Playgroud)

我的问题是这段代码是否泄漏内存?还假设另一种用法

int main()
{
     A * temp = new A(); 
     temp->addB(); 

     delete temp ; // 1 
}
Run Code Online (Sandbox Code Playgroud)

这里需要1吗?如果我有一个指向堆的指针,并且该指针超出范围,则对堆中的元素调用析构函数。我只是想确定这一点。谢谢 !

Lok*_*oki 5

为了更容易关联何时调用析构函数以及何时不调用析构函数,请使用以下经验法则:当回收对象的内存时,则调用该对象的析构函数(并且此后立即回收内存) 。

您的第一个示例不会泄漏任何内存。这就是为什么......您实际上创建了 2 个对象。

A和B。

A 在堆栈上。对象 A 的内存是在堆栈上隐式创建的。

B 是由您的代码在堆上显式创建的。

当 main() 返回时,堆栈上的每个对象都被销毁。即用于保存堆栈上对象成员(在本例中为对象 A)的内存正在被隐式回收。由于对象 (A) 实际上被销毁并且其内存被回收,因此 A 的析构函数被调用。

在 A 的析构函数中,您明确告诉运行时回收代码显式分配的所有内存(即当您调用删除时)。因此对象 B 的内存也被回收。

因此没有发生泄漏。

在第二个示例中,您再次创建 2 个对象 A 和 B。这里,两个对象的内存都驻留在堆中。这是由您的代码使用 new 运算符显式分配的。在这种情况下,您的代码永远不会回收为 A 分配的内存。即永远不会为 A 调用删除。

main() 的堆栈仅包含指向 A 的指针的内存。main() 堆栈本身不包含 A 的内存。因此,当 main() 返回时,被销毁的只是为 A 分配的内存。指向 A 的指针,而不是 A 本身。由于 A 的内存从未被回收,因此它从未被“销毁”。因此它的析构函数从未被调用,相应地“B”也从未被销毁。