C/C++使用Lu键树实现智能指针及检查内存泄露(一)

2014-11-24 07:36:08 · 作者: · 浏览: 0

欢迎访问Lu程序设计

C/C++使用Lu键树实现智能指针及检查内存泄露

1 说明

要演示本文的例子,你必须下载Lu32脚本系统。本文的例子需要lu32.dll、lu32.lib、C++格式的头文件lu32.h,相信你会找到并正确使用这几个文件。

用C/C++编译器创建一个控制台应用程序,复制本文的例子代码直接编译运行即可。

2 关于智能指针及Lu实现

由于 C/C++ 语言没有自动内存回收机制,程序员每次 malloc/new 出来的内存都要手动 free/delete。由于程序流程太复杂,程序员容易忘记 free/delete,造成内存泄露。C++用智能指针可以有效缓解这类问题,例如:std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::scoped_array、boost::shared_array、boost::weak_ptr、boost::intrusive_ptr等等,可谓种类繁多。

实际上,C/C++程序使用Lu脚本的键树系统也可以解决此类问题,而且程序员可以方便地查找哪块内存忘记了free/delete。阅读完本文,你就可以尝试使用Lu脚本系统查找你的C/C++程序是否存在内存泄露了。

关于Lu脚本键树系统,可以参考Lu编程指南,同时参考这个教程:C/C++使用Lu脚本字符串键树。

3 代码

代码1:实现智能指针

#include 
  
   
#include 
   
     #include "lu32.h" #pragma comment( lib, "lu32.lib" ) using namespace std; #define key_Simple (luPriKey_User-20) //将对该私有键加锁 #define imax 5 //私有键值最大数 void _stdcall Del_Simple(void *me); //销毁Simple的函数 class Simple //编写一个简单的类帮助测试 { public: int number; //数据 bool bDelete; //为帮助测试新增的数据,对象初始化时bDelete=false,对象销毁时bDelete=true Simple(int param=0) { //在类的初始化函数中增加以下几行代码 void *me,*NowKey=NULL; //为避免编译器发出警告进行初始化,实际上不需要 me=this; InsertKey((char *)&(me),sizeof(luVOID),key_Simple,this,Del_Simple,NULL,1,NowKey); //在Lu键树中注册键值 bDelete=false; number = param; cout << "Simple: " << number << endl; }; ~Simple() { //在类的初始化函数中增加以下几行代码 void *me; if(!bDelete) //如果用户手动delete { bDelete=true; me=this; DeleteKey((char *)&(me),sizeof(luVOID),key_Simple,Del_Simple,0); //在Lu键树中删除键值 } cout << "~Simple: " << number << endl; }; }; void _stdcall Del_Simple(void *me) //销毁Simple的函数,将注册到Lu
    系统,以实现自动销毁Simple { Simple *pSimple; pSimple=(Simple*)me; if(pSimple->bDelete==false) //如果用户忘记了delete { pSimple->bDelete=true; delete pSimple; //这是Lu系统自动delete } } LuData _stdcall OpLock_Simple(luINT m,LuData *Para,void *hFor,int theOperator) //Simple的运算符重载函数 { LuData a; a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0; //不对Simple类型的对象做运算,总返回nil return a; } void main(void) { Simple *pSimple[imax]; int i; if(!InitLu()) return; //初始化Lu LockKey(key_Simple,Del_Simple,OpLock_Simple); //在Lu键树中加锁键,只能存储Simple类型 for(i=0;i
     
     


运行结果:

Simple: 0
Simple: 1
Simple: 2
Simple: 3
Simple: 4

--- C++ delete 删除约1/2对象 ---

~Simple: 0
~Simple: 1

--- Lu系统解锁键并销毁全部对象 ---

~Simple: 2
~Simple: 4
~Simple: 3

代码2:查找未释放对象(内存)

#include <windows.h>
#include 
      
       
#include "lu32.h"

#pragma comment( lib, "lu32.lib" )

using namespace std;

#define key_Simple		(luPriKey_User-20)	//将对该私有键加锁
#define imax		5		//私有键值最大数

void _stdcall Del_Simple(void *me);		//销毁Simple的函数

class Simple		//编写一个简单的类帮助测试
{
public:
	int number;	//数据
	bool bDelete;	//为帮助测试新增的数据,对象初始化时bDelete=false,对象销毁时bDelete=true

	Simple(int param=0)
	{
		//在类的初始化函数中增加以下几行代码
		void *me,*NowKey=NULL;	//为避免编译器发出警告进行初始化,实际上不需要
		me=this;
		InsertKey((char *)&(me),sizeof(luVOID),key_Simple,this,Del_Simple,NULL,1,NowKey);	//在Lu键树中注册键值
		bDelete=false;

		number = param;
		cout << "Simple: " << number << endl;
	};

	~Simple()
	{
		//在类的初始化函数中增加以下几行代码
		void *me;
		if(!bDelete)	//如果用户手动delete
		{
			bDelete=true;
			me=this;
			DeleteKey((char *)&(me),sizeof(luVOID),key_Simple,Del_Simple,0);	//在Lu键树中删除键值
		}

		cout << "~Simple: " << number << endl;
	};
};
void _stdcall Del_Simple(void *me)	//销毁Simple的函数,将注册到Lu系统,以实现自动销毁Simple
{
	Simple *pSimple;

	pSimple=(Simple*)me;
	if(pSimple->bDelete==false)		//如果用户忘记了delete
	{
		pSimple->bDelete=true;
		delete pSimple;		//这是Lu系统自动delete
	}
}
LuData _stdcall OpLock_Simple(luINT m,LuData *Para,void *hFor,int theOperator)	//Simple的运算符重载函数
{
	LuData a;

	a.BType=luStaData_nil; a.VType=luStaData_nil; a.x=0;	//不对Simple类型的对象做运算,总返回nil
	return a;
}
int _stdcall GetKeySimpleva lue(char *KeyStr,int ByteNum,void *KeyValue)	//枚举Lu系统中指定键值类型的所有对象
{
	Simple *pSimple;

	pSimple=(Simple *)KeyValue;
	cout << "Simple->number: " << pSimple->number << endl;
	return 1;
}

void main(void)
{
	Simple *pSimple[imax];
	int i;
	char KeyStr[sizeof(luVOID)+1];	//枚举未销毁的对象用,长度比指针长度大1

	if(!InitLu()) return;	//初始化Lu

	LockKey(key_Simple,Del_Simple,OpLock_Simple);	//在Lu键树中加锁键,只能存储Simple类型

	for(i=0;i
        
        


运行结果:

Simple: 0
Simple: 1
Simple: 2
Simple: 3
Simple: 4

--- C++ delete 删除约1/2对象 ---

~Simple: 0
~Simple: 1

--- 使用Lu枚举未释放的所有对象 ---

Simple->number: 2
Simple->number: 4
Simple->number: 3

--- Lu系统解锁键并销毁全部对象 ---

~Simple: 2
~Simple: 4
~Simple: 3

代码3:效率测试之一,未使用Lu缓冲区

#inc