虚析构函数

从基类delete派生类不一定会导致内存泄露的,主要发生在,派生类没有动态分配内存的时候,这种情况是无需在派生类的析构函数里面做一个释放内存的动作的,而virtual析构函数就是为了保证派生类析构函数一定会调用,但是没有动态分配内存,其实都没有给出析构函数的必要了,更加不用做调用了:

#include <iostream>

using namespace std;

class tt
{};

class dd : public tt
{
    int i;
    public:
        virtual void xx(){}
};

int main()
{
    tt *p = new dd;

    delete p;

    cout  << sizeof(tt) << sizeof (dd) << endl;
}


 

这里tt比派生类小,tt在做继承结构的时候大小为0,独立存在的时候是1.而派生类是8,包括一个int,和一vptr。但是,直接delete基类的指针p,也是不会有内存泄露的,因为释放内存的步骤就是,先call基类的析构函数,这里没有做virtual 析构,所以遗漏了派生类的,之后就是释放内存,反正p指向了正确的内存,内存首尾都是有一个对应的cookie的,记录内存大小,自然之后分配的一个dd对象的内存是不会泄露部分的。
我们看看valgrind内存检测结果:

[root@localhost c_proj]# valgrind --leak-check=full ./a.out 
==2723== Memcheck, a memory error detector
==2723== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==2723== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==2723== Command: ./a.out
==2723== 
18
==2723== 
==2723== HEAP SUMMARY:
==2723==     in use at exit: 0 bytes in 0 blocks
==2723==   total heap usage: 1 allocs, 1 frees, 8 bytes allocated
==2723== 
==2723== All heap blocks were freed -- no leaks are possible
==2723== 
==2723== For counts of detected and suppressed errors, rerun with: -v
==2723== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 8)


 

明显没有内存泄露的。

再看一个有泄露的版本呵呵:

[root@localhost c_proj]# g++ -g derive.cc 
[root@localhost c_proj]# ./a.out 
112
[root@localhost c_proj]# cat derive.cc 
#include <iostream>

using namespace std;

class tt
{
    public:
    ~tt(){}
};

class dd : public tt
{
    char *p;
    int i;
    public:
        dd()
        {
            i = 100;
            p = new char;
        }
        virtual void xx(){}
        ~dd()
        {
            delete p;
        }
};

int main()
{
    tt *p = new dd;

    delete p;

    cout << sizeof(tt) << sizeof (dd) << endl;
}
[root@localhost c_proj]# valgrind --leak-check=full ./a.out 
==2910== Memcheck, a memory error detector
==2910== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==2910== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==2910== Command: ./a.out
==2910== 
112
==2910== 
==2910== HEAP SUMMARY:
==2910==     in use at exit: 1 bytes in 1 blocks
==2910==   total heap usage: 2 allocs, 1 frees, 13 bytes allocated
==2910== 
==2910== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
==2910==    at 0x400737F: operator new(unsigned int) (vg_replace_malloc.c:255)
==2910==    by 0x80488CD: dd::dd() (derive.cc:19)
==2910==    by 0x80487B7: main (derive.cc:30)
==2910== 
==2910== LEAK SUMMARY:
==2910==    definitely lost: 1 bytes in 1 blocks
==2910==    indirectly lost: 0 bytes in 0 blocks
==2910==      possibly lost: 0 bytes in 0 blocks
==2910==    still reachable: 0 bytes in 0 blocks
==2910==         suppressed: 0 bytes in 0 blocks
==2910== 
==2910== For counts of detected and suppressed errors, rerun with: -v
==2910== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 15 from 8)
[root@localhost c_proj]# 

所以简单修正一下就是了:

[root@localhost c_proj]# g++ -g derive.cc 
[root@localhost c_proj]# cat derive.cc 
#include <iostream>

using namespace std;

class tt
{
    public:
    virtual ~tt(){}
};

class dd : public tt
{
    char *p;
    int i;
    public:
        dd()
        {
            i = 100;
            p = new char;
        }
        virtual void xx(){}
        ~dd()
        {
            delete p;
        }
};

int main()
{
    tt *p = new dd;

    delete p;

    cout << sizeof(tt) << sizeof (dd) << endl;
}
[root@localhost c_proj]# valgrind --leak-check=full ./a.out 
==2921== Memcheck, a memory error detector
==2921== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==2921== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==2921== Command: ./a.out
==2921== 
412
==2921== 
==2921== HEAP SUMMARY:
==2921==     in use at exit: 0 bytes in 0 blocks
==2921==   total heap usage: 2 allocs, 2 frees, 13 bytes allocated
==2921== 
==2921== All heap blocks were freed -- no leaks are possible
==2921== 
==2921== For counts of detected and suppressed errors, rerun with: -v
==2921== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 8)
[root@localhost c_proj]# 


 

所以虚析构函数还是需要的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值