#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