nothrow new

I suppose this makes me a bad programmer. Very well.

Programmer geek stuff follows...

Because Visual C++ 6.0 has, until very recently, been my C++ compiler of choice, I've been writing code like this:

CBobRun * pRunBobRun = new CBobRun();
if (pRunBobRun == NULL) complain;

I did not know that newer compilers will throw an exception if new fails. But now I know. And yes, I learned the hard way.

Deep inside a library I wrote, lives a little memory buffer class. You tell it to allocate a chunk of memory, and it does. When you're done with it, it frees the memory and everybody is happy. This class is the heart of many of my apps. But when I moved one of those apps to Visual Studio 2008, I started getting reports of strange crashes and failures. After a week of digging and working back and forth with one of these users, I found the problem. You can probably guess what it was.

Because this particular user was telling the app to do something way out past the limits of what I expected a user to do, 'new' was failing as it tried to allocate a huge amount of memory; and instead of failing quietly, as I thought it would, new was throwing an exception. Since I wasn't expecting the exception, there was nothing in place to catch it... well, almost nothing.

Way up at the top-level of the app was a "catch(...)", and it caught that exception. But it did nothing but spit out a cryptic little error message in response. And, for some reason, it took me four or five days before I could even get the failure to happen. Gah.

So now, via the magic of search & replace, I've turned all my news into:

CBobRun * pRunBobRun = new (std::nothrow) CBobRun();
if (pRunBobRun == NULL) complain;

That form of new won't throw anything.

But I wonder what exciting problems this will create !

6 thoughts on “nothrow new

  1. The Modesto Kid

    I am kind of glad to be writing ANSI C code with all the casting and testing for NULL that that entails. Is new throwing an exception part of the C++ standard? I never heard of such a thing and would think there is at least a parameter you could pass to the compiler to override this — it breaks a lot of code (like yours).

  2. cleek

    yeah, it’s part of the standard, but MS was late to implementing the standard. i got tricked into thinking new didn’t throw anything because… well, it didn’t!

  3. Rob Caldecott

    How did you track the bug down in the end? I assume that this was the issue you mentioned when asking for memory checking apps on CP the other day?

    The C++ compiler that shipped with VS6 wasn’t great – the VS2008 one is much better. The STL that ships with VS6 blows as well. Boost is full of nasty hacks just for VS6 for example.

    Have you ever, for pure geek fun, tried gcc? Download the latest Qt Creator (which includes MinGW 4) and see if you can port your code to gcc for fun – it might uncover some other issues as you’ll get a different set if warnings to the MS compiler. Qt Creator is a great IDE as well Cleek – well worth a look, you know, if you’re into that sort of stuff.

    FWIW my old MFC code at work is *full* of NULL checks when calling new as well. :)

  4. cleek

    How did you track the bug down in the end?

    i added a catch(CException *e) to that really high level catch(…). that told me it was an “out of memory” exception. then i added a dozen try/catch things through the lower levels until i finally got it down to a single ‘new’.

    i’ve thought about porting some of my stuff. but, i know exactly where the problems would be: in the GDI code. yuck.

  5. Rob Caldecott

    You can use the Win32 API with gcc – it would just be a chance to play with a new IDE and compiler. You can use Qt Creator to develop Windows apps without using the Qt framework…

  6. cleek

    that might be worth trying.

    finding the time is the next big problem.

    i really hate the way a full time job eats all my play time.

Comments are closed.