#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
",
i, it->_ptr, it->_fileName.c_str(), it->_line);
sa->save("【 %d:】ptr:%p, file:%s, line:%d
",
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;
}