Wednesday, February 24, 2010

Detect memory allocation failure in C++


In C++, we use "new" to allocate a piece of memory. There are chances that the allocation may fail. Upon the failure of allocating memory, the developer may want to do some clean-up or logging. You may see this piece of code in some old programs:
char *p = new char[buffer_size];
if (!p) {
   // error handling ...
}
It worked in the last century, but not any more. The problem of this piece of code is that with the modern C++ compiler, the "error handling" part will never get hit. If the memory allocation fails, an exception would be thrown and the rest of code after the "new" would not run. Try it with this little program:
#include <iostream>
using namespace std;
int main()
{
   long buffer_size = 0x7fffffff;

   char *p = new char[buffer_size];

   if (p)
      cout << "OK" << endl;
   else
      cout << "Bad" << endl;

   return 0;
}
You could not see the printout of "Bad". Instead, the output would be:
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted
To add error handling, we need to capture this exception:
try {
   char *p = new char[buffer_size];
}
catch (std::bad_alloc) {
   // error handling ...
}
If you prefer to the old behavior of "new", you can still use the "nothrow" version of "new":
char *p = new(std::nothrow) char[buffer_size];
if (!p) {
   // error handling ...
}
However, it is no recommended.

1 comment:

Mihail said...

I advise you to use Deleaker ( http://deleaker.com/ ) - its a good tool to find and localize memory leaks!

 
Get This <