内存泄露——不包含头文件类的析构函数不执行

今天遇到一个很诡异的内存泄露,记录如下:

1.两个类,记为A,B。其中A有应指向B的指针;B也有指针成员,指向new出来的空间。两个类定义如下:

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="cpp">1.1文件A.h
class B;
class A{public:
    ~A();
public:
    B * m_pB;
...
};
1.2 文件A.cpp
#include "A.h"
A::~A()
{
    if(m_pB)
    {
        delete m_pB;
        m_pB = NULL; 
    }
}
1.3 文件B.h
<pre name="code" class="cpp"><pre name="code" class="cpp">class B{
public:
    B();
    ~B();
private:
    int * m_p0;
...
};
1.4 文件B.cpp
#include "B.h"
B::B()
{
    m_p0 = new int(NUM);
}
B::~B()
{
    if(m_p0)
    {
        delete m_p0;
        m_p0 = NULL;
    }
}


 
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">根据上述定义,可以看出:</span>

1)B类里有new的指针,因此需要自定义析构函数,否则会造成内存泄露;

2)A类中有B的指针(下面会用new来赋值),但A.h文件只是声明了B类,而不是包含B类的头文件。A.cpp文件也未包含B.h,因此也是看不到B类的定义的。

2.下面给出main函数:

</pre><pre name="code" class="cpp">#include "A.h"
#include "B.h"
int main()
{
    A * pA = new A;
    A.m_pB = new B();
    delete pA;
}


上述代码会造成内存泄露!


3.分析:

     理论上说,执行delete pA;会调用A的析构函数,而A的析构函数又会调用B的析构函数,B的析构函数析构new出来的数组空间。然而实际上并非如此,上述代码会造成内存泄露。原因如下:

执行delete pA;会调用A类的析构函数,这步没有错。A类的析构函数会执行delete m_pB; 这步并不会调用B类的析构函数,原因在于A类的析构函数看不到B类的定义,所以也就不知道B类定义了自己的析构函数,它只释放了B类占用的空间(不包括B类里m_p0指针指向的空间)。因此造成内存泄露。

解决方法很简单:在A.cpp中包含头文件B.h。


4.总结:

    这个代码是在VS2010里写的,我不确定上述问题是C++语法的问题,还是VS的问题。有上面的分析我搞明白了delete所做的工作,delete一个指针p,p指向的对象的大小size肯定是知道的,那么delete的功能就是释放从p开始,大小为size的连线空间。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值