Skip to content

Instantly share code, notes, and snippets.

@PixelClear
Created February 13, 2017 07:56
Show Gist options
  • Save PixelClear/55096d6066bf8c7e140b6955570dd663 to your computer and use it in GitHub Desktop.
Save PixelClear/55096d6066bf8c7e140b6955570dd663 to your computer and use it in GitHub Desktop.
#include<iostream>
#include <new>
#include <cassert>
/*
This Demos how to install class specific new_handler.
set_new_handler function has global scope.
So If you want to have class specific installation of handler this is utility class for it.
*/
template<class T>
class Out_Of_Memory
{
public:
static void MemoryFailure();
/*
Please see header file <new> and namespace std has code for global set_new_handler
which will for for global new operator.
We want class specific things so we are overloading this functions and operator.
*/
static new_handler set_new_handler(new_handler p);
void* operator new[](size_t size);
void operator delete[](void *ptr);
private:
/*
this function pointer will keep track of handler to call
when new fails to allocate memory for objects of class Out_Of_Memory
*/
static new_handler currentHandler ; //Declaration
};
template<class T>
new_handler Out_Of_Memory<T>::currentHandler; //Definition
/*
This function belongs to class Out_Of_Memory ans it will accept pointer to new function handler.
It will return oldHandler which might be previously set.
The global set_new_handler also works similarly.
*/
template<class T>
new_handler Out_Of_Memory<T>::set_new_handler(new_handler p)
{
new_handler oldHandler = currentHandler;
currentHandler = p;
return oldHandler;
}
template<class T>
void Out_Of_Memory<T>::MemoryFailure()
{
std::cout << " Unable to give any memory" <<std::endl;
assert(0);
}
template<class T>
void Out_Of_Memory<T>::operator delete[](void* ptr)
{
::operator delete(ptr);
}
template<class T>
void* Out_Of_Memory<T>::operator new[](size_t size)
{
/*
Here we will make global new operator aware of our class specific handler
*/
new_handler globalHandler = std::set_new_handler(currentHandler);
void* memory;
/*
Here global new operator truies to allocate memory .
If it failes to do so it will first call
Out_Of_Memory class handler as it was set as global handler.
If even after that it fails to allocate or get memory somehow
global new operator will throw bad_alloc exception.
This exception we are catching here.
To back propogate this exception to global new we reset
global handler again.
*/
try
{
memory = ::operator new(size_t); // Call to gloabal new inside overloaded new
}
catch(std::bad_alloc&)
{
std::set_new_handler(globalHandler);
throw;
}
/*
If memory was succesfully allocated restore back the original global handler
*/
std::set_new_handler(globalHandler);
return memory;
}
class X : public Out_Of_Memory<X>
{
/*
Here you may have design specific class implementation
*/
};
class Y : public Out_Of_Memory<Y>
{
/*
Here you may have design specific class implementation
*/
};
int main()
{
size_t big_number;
//Setting X class specific new_handler
X::set_new_handler(X::MemoryFailure);
//Setting Y class specific new_handler
Y::set_new_handler(Y::MemoryFailure);
// Allocate big memory that will make new fail
X *ptr_x = new X[big_number];
Y *ptr_y= new Y[big_number];
delete []ptr_x;
delete []ptr_y;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment