Created
February 13, 2017 07:56
-
-
Save PixelClear/55096d6066bf8c7e140b6955570dd663 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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