项目总结图:
项目代码:
TypeTraits.hpp
struct __TrueType
{
bool Get()
{
return true;
}
};
struct __FalseType
{
bool Get()
{
return false;
}
};
template <class _Tp>
struct TypeTraits
{
typedef __FalseType __IsPODType;
};
template <>
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;
};
MemoryManager.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<list>
#include<assert.h>
#include<stdarg.h>
#include"TypeTraits.hpp"
using namespace std;
// 保存适配器
class SaveAdapter
{
public:
virtual void Save(const char* fmt,...) = 0;
};
class ConsoleSaveAdapter:public SaveAdapter
{
public:
virtual void Save(const char* fmt, ...)
{
va_list arg;
va_start(arg, fmt);
//int vfprintf ( FILE * stream, const char * format, va_list arg );
vfprintf(stdout, fmt, arg);
va_end(arg);
}
};
class FileSaveAdapter:public SaveAdapter
{
public:
FileSaveAdapter(const char* filename = "memoryLeakReport.txt")
{
_fptr = fopen(filename, "w");
}
~FileSaveAdapter()
{
if (_fptr)
{
fclose(_fptr);
}
}
virtual void Save(const char* fmt, ...)
{
if (_fptr)
{
va_list arg;
va_start(arg, fmt);
vfprintf(_fptr, fmt, arg);
va_end(arg);
}
}
protected:
FileSaveAdapter(const FileSaveAdapter& f);
FileSaveAdapter& operator=(FileSaveAdapter& f);
protected:
FILE* _fptr;
};
struct BlockInfo //内存块信息
{
void* _ptr;
string _file;
int _line;
BlockInfo(void* ptr, string file, int line)
:_ptr(ptr)
, _file(file)
, _line(line)
{}
};
//单例模式
//封装
//保证全局中只有一个实例对象
//很容易被外界所获取到这个实例
class Singleton
{
public:
static Singleton* GetInstance();
void* Alloc(size_t size, string file, int line);//分配空间
void Dealloc(void* ptr);//释放空间
//持久化
static void Persistent();
void _Persistent(SaveAdapter* sa);//打印内存泄漏的内存块信息
private:
Singleton(){};
Singleton(const Singleton & s);
Singleton& operator=(const Singleton &s);
protected:
list<BlockInfo> _blockList;
static Singleton* sInstance;
};
#define NEW(type) \
__NEW<type>(sizeof(type), __FILE__, __LINE__)
#define DELETE(ptr) \
__DELETE(ptr)
#define NEW_ARRAY(type,num) \
__NEW_ARRAY<type>(sizeof(type)*num, __FILE__, __LINE__)
#define DELETE_ARRAY(ptr)\
__DELETE_ARRAY(ptr)
template<class T>
T* __NEW(size_t size, const char* file, int line)
{
T* ptr = (T*)Singleton::GetInstance()->Alloc(size, file, line);
//new定位表达式调用构造函数初始化
return new(ptr)T;
}
template<class T>
void __DELETE(T* ptr)
{
ptr->~T();
Singleton::GetInstance()->Dealloc(ptr);
}
template<class T>
T* __NEW_ARRAY(size_t size, const char*file, int line)
{
bool isPodType = TypeTraits<T>::__IsPODType().Get();
if (isPodType)
{
T* ptr = (T*)Singleton::GetInstance()->Alloc(size, file, line);
return ptr;
}
else
{
T* p = (T*)Singleton::GetInstance()->Alloc(size + 4, file, line);
int num = size / sizeof(T);
*(int*)p = num;
T* ptr = (T*)((int*)p + 1);
//运用new的定位表达式调用构造函数实例化对象
T* tmp = ptr;
while (num--)
{
new(tmp)T;
tmp++;
}
return ptr;
}
}
template<class T>
void __DELETE_ARRAY(T *ptr)
{
bool isPodType = TypeTraits<T>::__IsPODType().Get();
if (isPodType)
{
Singleton::GetInstance()->Dealloc(ptr);
}
else
{
T* tmp = ptr;
int* tmp1 = (int*)ptr;
int num = *(--tmp1);
//显示的调用num次析构函数
while (num--)
{
tmp->~T();
tmp++;
}
Singleton::GetInstance()->Dealloc(tmp1);
}
}
MemoryManager.cpp
#include"MemoryManager.h"
void* Singleton::Alloc(size_t size, string file, int line)
{
void* ptr = malloc(size);
if (ptr != NULL)
{
BlockInfo info(ptr, file, line);
_blockList.push_back(info);
}
return ptr;
}
void Singleton::Dealloc(void* ptr)
{
free(ptr);
if (ptr != NULL)
{
list<BlockInfo>::iterator it = _blockList.begin();
while (it != _blockList.end())
{
if (it->_ptr == ptr)
{
_blockList.erase(it);
return;
}
it++;
}
assert(false);
}
}
void Singleton::_Persistent(SaveAdapter* sa)
{
list<BlockInfo>::iterator it = Singleton::_blockList.begin();
while (it != _blockList.end())
{
int i=1;
//printf("ptr:%p\nfile:%s\nline:%d\n", it->_ptr,it->_file.c_str() ,it->_line);
sa->Save("【内存泄露%d:】ptr:%p, file:%s, line:%d\n",
i, it->_ptr, it->_file.c_str(), it->_line);
it++;
cout << "\n";
}
}
void Singleton::Persistent()
{
ConsoleSaveAdapter csa;
GetInstance()->_Persistent(&csa);
FileSaveAdapter fsa;
GetInstance()->_Persistent(&fsa);
}
Singleton* Singleton::sInstance = NULL;
Singleton* Singleton::GetInstance()
{
if (sInstance == NULL)
{
sInstance = new Singleton;
}
return sInstance;
}
Test.cpp
#include"MemoryManager.h"
class AA
{
public:
AA()
{
cout << "A()" << endl;
}
~AA()
{
cout << "~A()"<<endl;
}
};
void Test1()
{
AA* p1=NEW(AA);
DELETE(p1);
int* p2 = NEW(int);
DELETE(p2);
AA*p3 = NEW_ARRAY(AA,10);
DELETE_ARRAY(p3);
double* p4 = NEW_ARRAY(double, 8);
DELETE_ARRAY(p4);
}
int main()
{
// 登记一个函数在main函数执行结束以后执行
atexit(&Singleton::Persistent);
Test1();
system("pause");
return 0;
}
《完》
转载于:https://blog.51cto.com/lingdandan/1827497