[C++之AOP]实战Aspect C++之检查内存泄漏

前面简单介绍了Aspect C++,相信没人看出它有什么特别强大的地方。

这次特别挑了一个合适的例子,检查内存泄漏。

首先看一个普通的程序:
1、test.h
#ifndef __TEST_H__
#define  __TEST_H__

class  Test1
{
};

class  Test2
{
};

class  Test3
{
};

#endif   //  __TEST_H__
2、main.cc
#include  " test.h "

int  main ()
{
    Test1 test1;
    Test2 test2;
    Test3 test3;

    
new  Test1();
    
new  Test2();
    
new  Test2();
    
new  Test1();

    
new  Test1(test1);
    
new  Test3(test3);
    
return   0 ;
}

这个程序会有6个对象泄漏。如果是在很隐蔽的地方分配对象,如何能够快速查找出来呢?

采用Aspect C++,我们可以在构造函数和析构函数中插入代码,帮助检查内存泄漏。

首先实现一个内存分配记录管理器:
1、memory_recorder.h
#ifndef __MEMORY_RECORDER_H__
#define  __MEMORY_RECORDER_H__

#include 
< map >
#include 
< typeinfo >
using   namespace  std;

class  MemoryRecorder
{
    map
< void * const  type_info *>  objects;
public :
    
~ MemoryRecorder ();
    
void  addObject( void *  obj,  const  type_info &  ti);
    
void  removeObject( void *  obj,  const  type_info &  ti);
};

extern  MemoryRecorder g_memoryRecorder;

#endif   //  __MEMORY_RECORDER_H__
2、memory_recorder.cc
#include  " memory_recorder.h "

#include 
< iostream >
using   namespace  std;


MemoryRecorder g_memoryRecorder;


MemoryRecorder::
~ MemoryRecorder ()
{
    
if  (objects.size()  >   0 )
    {
        cout 
<<  objects.size()  <<   "  objects not released: "   <<  endl;
        
for  (map < void * const  type_info *> ::const_iterator iter  =  objects.begin();
            iter 
!=  objects.end();
            iter 
++ )
        {
            cout 
<<   " \t "   <<  iter -> second -> name()  <<   " "   <<  (iter -> first)  <<  endl;
            delete (iter
-> first);
        }
    }
}

void  MemoryRecorder::addObject( void *  obj,  const  type_info &  ti)
{
    objects.insert(make_pair(obj, 
& ti));
}

void  MemoryRecorder::removeObject( void *  obj,  const  type_info &  ti)
{
    objects.erase(obj);
}
3、实现方面,test.ah
#ifndef __TEST_AH__
#define  __TEST_AH__

#include 
" memory_recorder.h "
#include 
< iostream >
using   namespace  std;

aspect MemberRecorder
{
    pointcut all_class() 
=  classes( " Test% " );

    advice construction (all_class()) : after ()
    {
        g_memoryRecorder.addObject (tjp
-> target(), typeid( * tjp -> target()));
    }

    advice destruction (all_class()) : after ()
    {
        g_memoryRecorder.removeObject (tjp
-> target(), typeid( * tjp -> target()));
    }
};

#endif   //  __TEST_AH__

这个方面实现的功能很简单,首先定义了一个pointcut(切面),它匹配所有以“Test”开头的类。
接下来定义了2个处理方法,分别在这些类的构造函数和析构函数调用之后执行。

tjp->target()指向Test*对象实例,其它的不详细说明了,应该都比较容易懂。

顺便说一下,前一篇里说源文件可以保存为.cpp文件,实际上是错误的,它只处理.h和.cc文件。

运行ac++产生代码,编译运行后效果如下:
F:\projects\aspectc-out>main
6 objects not released:
        class Test1: 00372B40
        class Test1: 00372B70
        class Test3: 00372BA0
        class Test1: 00374F90
        class Test2: 00374FC0
        class Test2: 00374FF0

另外,产生代码时最好是使用mingw,配置方便一些,不影响产生后的代码,产生后的代码可以使用VC编译。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值