#pragma once //头文件
#include<iostream>
#include<string.h>
#include<list>
#include "TypeTraits.hpp" //类型萃取
#include <stdarg.h>
using namespace std;
struct SaveAdapter//保存适配器 基类
{
virtual void save(const char* fmt, ...) = 0;//定义可变参数列表的 纯虚函数(用于被子类重写)
};
class ConsoleSaveAdapter : public SaveAdapter //控制台下的保存适配器
{
virtual void save(const char* fmt, ...);//重写 基类虚函数 将信息输出到屏幕
};
class FileSaveAdapter :public SaveAdapter //基于文件(写入文件)的保存适配器
{
public:
FileSaveAdapter(const char* filename="MemoryLeakReport.txt");// 构造函数 打开日志文本文件
~FileSaveAdapter(); //析构函数 关闭保存日志文件
virtual void save(const char* fmt, ...); //写入信息
protected:
FileSaveAdapter(const FileSaveAdapter&); //拷贝构造只声明不定义
void operator=(const FileSaveAdapter&);
private:
FILE *fOut; //声明文件指针
};
struct BlockInfo //定义 开辟堆内存信息提取 类
{
void* _ptr; //指向堆内存指针
string _fileName; //保存/打印内存泄漏信息时的文件名
int _line; //......行号
string _type; //类型名
int size; //大小
BlockInfo(void* ptr = NULL, char* fileName = "", int num = 0); //构造函数
};
class Singleton //单例模型 (保证全局只有唯一的一个 内存管理 链表)
{
public:
static Singleton *GetInstance(); //静态 函数 可通过类型名直接调用 (保证对象唯一)
void* Alloc(size_t size, char* filename, int line);//自己实现 动态开辟内存
void DeAlloc(void* ptr); //释放内存
static void Persistent(); //静态打印信息函数 调用 _persistent()
private:
Singleton()
{}
Singleton(Singleton&); //
Singleton& operator=(Singleton&); //只声明不定义
void _persistent(SaveAdapter* sa); //内部打印信息 函数 可被 Persistent()调用
protected:
static Singleton* sInstance; //静态 单例类型指针
list<BlockInfo> _BlockList; // 堆内存管理链表(调用<list>库函数中)
};
template<class T>
T* _NEW(size_t size, char* filename, int line) //模板函数 NEW 模拟new关键字
{
T* ptr;
if (size > 1)
{
size_t num = sizeof(T)*size;
if (!TypeTraits<T>::__IsPODType().Get())//类型萃取
{
ptr = (T*)Singleton::GetInstance()->Alloc(num + 4, filename, line);//非基本类型多开辟4字节 记录数组类型大小 用于析构时的计数
*(int*)ptr = num;
ptr=(T*)((int*)ptr+1);
}
else
ptr = (T*)Singleton::GetInstance()->Alloc(num , filename, line);//Singleton 对象的调用
for (size_t i = 0; i <size; ++i)
{
new(ptr + i) T; //new 的初始化列表功能
}
return ptr;
}
else
ptr = (T*)Singleton::GetInstance()->Alloc(sizeof(T), filename, line);
return new(ptr) T;
}
//定义宏 (使 NEW的 调用方法接近 关键字 new)
#define NEW(Type) _NEW<Type>(1,__FILE__,__LINE__)
template<class T>
void _DELETE(T* ptr)
{
ptr->~T();
Singleton::GetInstance()->DeAlloc(ptr);
}
template<class T>
void _DELETE_ARRAY(T* ptr)
{
if(!TypeTraits<T>::__IsPODType().Get())
{
size_t num= *((int*)ptr - 1);
for (size_t i = 0; i < num; ++i)
{
ptr[i].~T();
}
}
Singleton::GetInstance()->DeAlloc((int*)ptr - 1);
}
#define DELETE(ptr) _DELETE(ptr)
#define NEW_ARRAY(Type,size) _NEW<Type>(size, __FILE__, __LINE__)
#define DELETE_ARRAY(ptr) _DELETE_ARRAY(ptr)
#include"memorymanagar.h" //函数定义文件
#include<assert.h>
using namespace std;
BlockInfo::BlockInfo(void* ptr,char* fileName,int num)//构造 BlockInfo
: _ptr(ptr)
, _fileName(fileName)
, _line(num)
{}
Singleton* Singleton::sInstance = NULL; //类中静态变量 必须在类外定义(初始化)
Singleton* Singleton::GetInstance()
{
if (sInstance == NULL)
{
sInstance = new Singleton;
}
return sInstance;
}
void* Singleton::Alloc(size_t size, char* filename, int line)
{
void * ptr = malloc(size);
if (ptr)
{
BlockInfo tmp(ptr, filename, line); //生成 节点
_BlockList.push_back(tmp); //调用库 中链表操作
}
return ptr;
}
void Singleton::DeAlloc(void* ptr)
{
free(ptr);
if (ptr)
{
list<BlockInfo>::iterator it = _BlockList.begin(); //调用迭代器 用于删除节点
while (it != _BlockList.end())
{
if (it->_ptr == ptr)
{
_BlockList.erase(it);
return;
}
++it;
}
}
assert(0);
}
void Singleton::Persistent() //外部接口 (打印信息)
{
FileSaveAdapter file;
GetInstance()->_persistent(&file);
}
void Singleton::_persistent(SaveAdapter* sa) //内部函数 (实现打印信息)
{
int i = 1;
std::list<BlockInfo>::iterator it = _BlockList.begin();
while (it != _BlockList.end())
{
printf("【内存泄露%d:】ptr:%p, file:%s, line:%d\n",
i, it->_ptr, it->_fileName.c_str(), it->_line);
sa->save("【内存泄露%d:】ptr:%p, file:%s, line:%d\n",
i, it->_ptr, it->_fileName.c_str(), it->_line);
++it;
}
}
void ConsoleSaveAdapter::save(const char* fmt, ...) //
{
va_list args;
va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);
}
FileSaveAdapter::FileSaveAdapter(const char* filename )
{
fOut = fopen(filename, "w");
}
FileSaveAdapter::~FileSaveAdapter()
{
if (fOut)
fclose(fOut);
}
void FileSaveAdapter::save(const char* fmt, ...)
{
if (fOut)
{
va_list args;
va_start(args, fmt);
vfprintf(fOut, fmt, args);
va_end(args);
}
}
//类型萃取
#pragma once
#include<iostream>
using namespace std;
struct __TrueType//定义类 普通类型(基本类型的)
{
bool Get()
{
return true;
}
};
struct __FalseType//定义类 非基本类型
{
bool Get()
{
return false;
}
};
template <class _Tp>//模板类 (类型萃取)
struct TypeTraits //非基本类型
{
typedef __FalseType __IsPODType;//*****************************************************/
}; //将基本类型类 与非基本类型类 重命名(typedef)为相同名 :__IsPODType
//调用__IsPODType().Get() 时编译器会根据TypeTraits<class T> T 的实际类型调用
template <> //特化基本类型 bool //__FalseType 或 Truetype 的 Get()函数 得到不同 bool值
struct TypeTraits< bool> // 以下下为常用基本类型特化
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< char>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< unsigned char >
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< short>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< unsigned short >
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< int>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< unsigned int >
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< long>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< unsigned long >
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< long long >
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< unsigned long long>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< float>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< double>
{
typedef __TrueType __IsPODType;
};
template <>
struct TypeTraits< long double >
{
typedef __TrueType __IsPODType;
};
template <class _Tp>
struct TypeTraits< _Tp*>
{
typedef __TrueType __IsPODType;
};
//主函数 测试文件
#include<iostream>
#include"memorymanagar.h"
//void Test1()
//{
// int* p1 = (int*)Alloc(sizeof(int)*10, __FILE__, __LINE__);
// int* p2 = (int*)Alloc(sizeof(int)*10, __FILE__, __LINE__);
// int* p3 = (int*)Alloc(sizeof(int)*10, __FILE__, __LINE__);
// int* p4 = (int*)Alloc(sizeof(int)*10, __FILE__, __LINE__);
//
// Dealloc(p2);
// Dealloc(p4);
//}
class AA
{
public:
AA()
{
cout << "AA()" << endl;
}
~AA()
{
cout << "~AA()" << endl;
}
};
void Test1()
{
// new/delete
// AA* p1 = _NEW<AA>(sizeof(AA), __FILE__,__LINE__);
//AA* p1 = NEW(AA);// new AA
//DELETE(p1); // delete p1;
//int* p4 = NEW(int);// new AA
//DELETE(p4); // delete p1;
AA* p2 = NEW_ARRAY(AA, 10);
DELETE_ARRAY(p2);
int* p3 = NEW_ARRAY(int, 10);
//DELETE_ARRAY(p3);
}
int main()
{
// 登记一个函数在main函数执行结束以后执行
atexit(&Singleton::Persistent);
Test1();
return 0;
}原文地址:http://shaungqiran.blog.51cto.com/10532904/1730649