#include <iostream>
#include <algorithm>
#include <functional>
#include "gttest.h"
#include "allocator.h"
/*===============================================*/
/* MemoryInfo */
/*===============================================*/
struct MemoryInfo
{
void* address; //!< アドレス
const char* file; //!< ファイル
int line; //!< ライン
};
/*===============================================*/
/* DefaultAllocator */
/*===============================================*/
//-----------------------------------------------
DefaultAllocator::DefaultAllocator()
{
}
//-----------------------------------------------
DefaultAllocator::~DefaultAllocator()
{
}
//-----------------------------------------------
DefaultAllocator* DefaultAllocator::Get()
{
static DefaultAllocator instance;
return &instance;
}
//-----------------------------------------------
void* DefaultAllocator::Allocate( size_t s, const char*, int )
{
return ::operator new ( s );
}
//-----------------------------------------------
void DefaultAllocator::Deallocate( void* p )
{
::operator delete ( p );
}
/*===============================================*/
/* AllocateManager */
/*===============================================*/
//-----------------------------------------------
AllocateManager::AllocateManager()
:m_alloc( NULL )
{
Set( NULL );
}
//-----------------------------------------------
AllocateManager::~AllocateManager()
{
}
//-----------------------------------------------
void* AllocateManager::Allocate( size_t s, const char* f, int l )
{
return m_alloc->Allocate( s, f, l );
}
//-----------------------------------------------
void AllocateManager::Deallocate( void* p )
{
m_alloc->Deallocate( p );
}
//-----------------------------------------------
void AllocateManager::Set( IAllocator* alloc )
{
if( alloc ) m_alloc = alloc;
else m_alloc = DefaultAllocator::Get();
}
/*===============================================*/
/* Alloc */
/*===============================================*/
//-----------------------------------------------
Alloc::Alloc()
:m_manager()
{
}
//-----------------------------------------------
Alloc* Alloc::Get()
{
static Alloc instance;
return &instance;
}
//-----------------------------------------------
void* Alloc::Allocate( size_t s, const char* f, int l )
{
return m_manager.Allocate( s, f, l );
}
//-----------------------------------------------
void Alloc::Deallocate( void* p )
{
m_manager.Deallocate( p );
}
//-----------------------------------------------
void Alloc::Set( IAllocator* alloc )
{
m_manager.Set( alloc );
}
/*===============================================*/
/* BaseAllocator */
/*===============================================*/
//-----------------------------------------------
BaseAllocator::BaseAllocator()
{
Alloc::Get()->Set( this );
}
//-----------------------------------------------
BaseAllocator::~BaseAllocator()
{
Alloc::Get()->Set( NULL );
}
/*===============================================*/
/* Allocator */
/*===============================================*/
//-----------------------------------------------
Allocator::Allocator()
:m_container()
{
}
//-----------------------------------------------
Allocator::~Allocator()
{
if( m_container.empty() == false ) {
std::cout << "MEMORY_LEAK!!" << std::endl;
struct Print : public std::unary_function< MemoryInfo*, void >
{
void operator () ( MemoryInfo* mem )
{
std::cout << "FILE: " << mem->file << std::endl;
std::cout << " LINE: " << mem->line << std::endl;
}
};
struct Delete : public std::unary_function< MemoryInfo*, void >
{
void operator () ( MemoryInfo* mem )
{
delete( mem->address );
delete( mem );
}
};
std::for_each( m_container.begin(), m_container.end(), Print() );
std::for_each( m_container.begin(), m_container.end(), Delete() );
}
}
//-----------------------------------------------
void* Allocator::Allocate( size_t s, const char* f, int l )
{
MemoryInfo* mem = new MemoryInfo();
mem->address = ::operator new( s );
mem->file = f;
mem->line = l;
m_container.push_back( mem );
return mem->address;
}
//-----------------------------------------------
void Allocator::Deallocate( void* p )
{
iterator beg( m_container.begin() ), end( m_container.end() );
for( ; beg!=end; ++beg ) {
if( (*beg)->address == p ) {
delete( (*beg) );
m_container.erase( beg );
break;
}
}
::operator delete( p );
}
//-----------------------------------------------
bool Allocator::Check() const
{
return m_container.empty();
}
最終更新:2009年02月14日 15:52