Skip to content

Instantly share code, notes, and snippets.

@PixelClear
Created February 10, 2017 07:00
Show Gist options
  • Save PixelClear/bd482ec691fb19548a392570947b6721 to your computer and use it in GitHub Desktop.
Save PixelClear/bd482ec691fb19548a392570947b6721 to your computer and use it in GitHub Desktop.
#include<iostream>
#include<new>
#include<cassert>
using std::cout;
using std::cin;
using std::endl;
namespace Numbers
{
/* --------------------------------------------Memory Pool--------------------------------------*/
template<class T>
class MemoryPool
{
private:
//Using const that #defines
static const int BLOCK_SIZE;
//Wants only class wide vopy
static T *head;
static T *newBlock;
public:
MemoryPool();
void * alloc(size_t size);
void free_(void* p, size_t size);
~MemoryPool();
};
//Static definations
template<class T>
const int Numbers::MemoryPool<T>::BLOCK_SIZE = 512;
template<class T>
T* Numbers::MemoryPool<T>::head;
template<class T>
T* Numbers::MemoryPool<T>::newBlock;
template<class T>
Numbers::MemoryPool<T>::MemoryPool()
{
}
template<class T>
Numbers::MemoryPool<T>::~MemoryPool()
{
::operator delete(newBlock);
}
template<class T>
void* Numbers::MemoryPool<T>::alloc(size_t size)
{
/*If derived class doesnt implement new and calls new here we handle case
This case also handles when size is zero as objects size cant be zero
in case of zero size we will fall back to global new. So we are not flexible
but we are fast*/
if(size != sizeof(T))
return ::operator new(size); // Let the global new handle the case
T *p = head;
if(p != NULL)
head = p->next;
else
{
/*Allocate huge block and make list out of it*/
if(newBlock == NULL)
newBlock = static_cast<T*>(::operator new(BLOCK_SIZE * sizeof(T)));
for(int i = 1; i < BLOCK_SIZE-1; i++)
newBlock[i].next = & newBlock[i+1];
newBlock[BLOCK_SIZE-1].next = NULL;
p = newBlock; // return 0th block
head = &newBlock[1]; // head points to 1s element now
}
return p;
}
template <class T>
void Numbers::MemoryPool<T>::free_(void* ptr, size_t size)
{
if(ptr == 0) // handle case with deleting null pointer
return;
if(size != sizeof(Integer))
{
::operator delete(ptr);
return;
}
T* freeBlock = static_cast<T*>(ptr);
freeBlock->next = head;
head = freeBlock;
}
/* --------------------------------------------Memory Pool Ends--------------------------------------*/
class Integer
{
public :
Integer(){}
~Integer(){
cout << "Inside ~Integer()"<<endl;
}
static void * operator new(size_t size);
static void operator delete(void *p, size_t size);
struct
{
int data;
Integer* next;
};
};
//Memory Pool is in namespace
Numbers::MemoryPool<Numbers::Integer> memPool;
/*We are based on assumption on builing blocks because we know size request we will get
will be equal to Integer class so we skip lot of book keeping, memory fragmentation and
all steps so this version will be faster that global new*/
inline void* Numbers::Integer::operator new(size_t size)
{
return memPool.alloc(size);
}
/*Delete will recieve block of memory if it is of size of Integer
we will add this block to head of list*/
inline void Numbers::Integer::operator delete(void* ptr, size_t size)
{
memPool.free_(ptr,size);
}
};
int main()
{
Numbers::Integer *i1 = new Numbers::Integer;
i1->data = 10;
Numbers::Integer *i2 = new Numbers::Integer;
i2->data = 20;
delete i1;
delete i2;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment