Tuesday, January 4, 2011

Throwing non-throwing operator new

When we write
foo *p = new(std::nothrow) foo;

we still have probability of uncatched bad_alloc.
The following code may look confusing (and it does),
though it works perfect

try {
        p = new(std::nothrow) foo;
} catch (std::bad_alloc&) {
        exit(0); //nevermind
}


The `problem' could be in foo::foo, e.g.
foo::foo() {
        member = new int[0x7fffffff];
}


since nothrow_t works only for outer allocation and
leaves room for bad_alloc in .ctor.

operator new (std::size_t sz, const std::nothrow_t&) throw()
{
  void *p;

  /* malloc (0) is unpredictable; avoid it.  */
  if (sz == 0)
    sz = 1;
  p = (void *) malloc (sz);
  while (p == 0)
    {
      new_handler handler = __new_handler;
      if (! handler)
        return 0;
      __try
        {
          handler ();
        }
      __catch(const bad_alloc&)
        {
          return 0;
        }

      p = (void *) malloc (sz);
    }

  return p;
}

No comments:

Post a Comment