c++ブロックメモリ管理


#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; }