Scott Meyers: Item 7, new operator exception handling
Sep 19, 2012 at 6:22pm UTC
Hi Guys,
I'm working through Scott Meyer's Effective C++ and I am on Item 7, which is exception handling for the new operator.
I've implemented his example of using a base class to provide custom exception handling functionality to any class, but my code doesn't do what I'd expect it to. Could anybody help me?
I would expect that this should call myfun() and print my message, but it's not doing so.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
#include <iostream>
#include <new>
/******************************************************************************************/
template <class X>
class NewHandlerSupport
{
public :
/// new operater using this class
static void * operator new (size_t size);
/// set a new_handler for this class
static std::new_handler set_new_handler(std::new_handler);
private :
static std::new_handler m_handler;
};
template <class X>
std::new_handler NewHandlerSupport<X>::m_handler(0); // default value
template <class X>
void * NewHandlerSupport<X>::operator new (size_t size)
{
// temporarily switch in m_handler
std::new_handler current_handler = std::set_new_handler(m_handler);
// allocate
void * memory;
try
{
memory = ::operator new (size);
}
catch (const std::bad_alloc&)
{
// restore handler and propogate exception
std::set_new_handler (current_handler);
throw ;
}
// restore handler
std::set_new_handler (current_handler);
return memory;
}
template <class X>
std::new_handler NewHandlerSupport<X>::set_new_handler(std::new_handler h)
{
std::new_handler old = m_handler;
m_handler = h;
return old;
}
/******************************************************************************************/
/// An example of a class using this
class X : public NewHandlerSupport<X>
{
public :
X() { throw std::bad_alloc(); }
};
void myfun() { std::cerr << "Handler for X" << std::endl; }
int main()
{
X::set_new_handler(myfun);
X* x = new X;
}
Thanks!
Sep 19, 2012 at 8:06pm UTC
Why would it call myfun? new didn't fail to allocate memory. You just threw an arbitrary exception.
Sep 20, 2012 at 12:05pm UTC
Cool, understood. Cheers
Sep 20, 2012 at 1:31pm UTC
To test your code, just force an
::operator new ()
failure. For instance:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
struct X
{
static void * operator new ( std::size_t sz ) { return ::operator new (-1) ; }
};
void my_new_handler()
{
static int n = 0 ;
std::clog << '\t' << ++n << ". my_new_handler was called\n" ;
if ( n == 5 )
{
std::set_new_handler(nullptr ) ;
std::clog << "*** my_new_handler removed\n" ;
}
}
int main()
{
std::set_new_handler(my_new_handler) ;
std::clog << "*** my_new_handler installed\n" ;
try { new X ; }
catch ( const std::exception& e ) { std::cerr << "error: " << e.what() << '\n' ; }
}
Topic archived. No new replies allowed.