假设一个类及其用法
#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
}
我的问题是此代码是否会泄漏内存?还假设另一种用法
int main()
{
A * temp = new A();
temp->addB();
delete temp ; // 1
}
这里需要1吗?如果我有一个指向堆的指针,并且指针超出范围,则是在堆中的元素上调用的析构函数。我只想确定这一点。谢谢 !
为了使关联更容易关联何时将调用析构函数以及何时不调用析构函数,请使用以下经验法则:当回收对象的内存时,将调用对象的析构函数(然后在此之后回收内存) 。
您的第一个示例不会泄漏任何内存。这就是原因...您实际上创建了2个对象。
A和B。
A在堆栈上。对象A的内存是在堆栈上隐式创建的。
B是由您的代码在堆上显式创建的。
当main()返回时,堆栈上的每个Object均被销毁。也就是说,隐式回收了用于将对象的成员保存在堆栈上的内存(在本例中为对象A)。由于对象(A)实际上已被销毁并回收了其内存,因此将调用A的析构函数。
在A的析构函数中,您明确地告诉运行时回收所有内存,这些内容是由代码显式分配的(即,当您调用delete时)。因此,对象B的内存也被回收。
因此没有泄漏。
在第二个示例中,您再次创建2个对象A和B。在这里,这两个对象的内存都位于堆中。这是由您的代码使用new运算符显式分配的。在这种情况下,您的代码永远不会回收分配给A的内存。即,永远不会为A调用delete。
main()的堆栈仅包含指向A的指针的内存。main()堆栈本身不包含A的内存。因此,当main()返回时,所有被破坏的是分配给A的内存。指向A的指针,而不是A本身。由于从未回收A的内存,因此它从未被“破坏”。因此,它的析构函数从未被调用过,相应地,“ B”也从未被破坏。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句