前面简单介绍了Aspect C++,相信没人看出它有什么特别强大的地方。
这次特别挑了一个合适的例子,检查内存泄漏。
首先看一个普通的程序:
1、test.h
这个程序会有6个对象泄漏。如果是在很隐蔽的地方分配对象,如何能够快速查找出来呢?
采用Aspect C++,我们可以在构造函数和析构函数中插入代码,帮助检查内存泄漏。
首先实现一个内存分配记录管理器:
1、memory_recorder.h
这次特别挑了一个合适的例子,检查内存泄漏。
首先看一个普通的程序:
1、test.h
#ifndef __TEST_H__
#define __TEST_H__
class Test1
{
};
class Test2
{
};
class Test3
{
};
#endif // __TEST_H__
2、main.cc
#define __TEST_H__
class Test1
{
};
class Test2
{
};
class Test3
{
};
#endif // __TEST_H__
#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 ;
}
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
#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__
#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
#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);
}
#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__
#define __TEST_AH__
#include " memory_recorder.h "
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__