Hey,
So basically I'm using dynamic memory allocation, and I wanted to add in a check for if the new operator can't complete the request. I've read up that the operator will return a std::bad_alloc, but I've no idea how that helps me.

Could I just do?:

if (new int[999] == std::bad_alloc)
    cout << "Ooops!";

Help, or hints would be appreciated!

Ed

std::bad_alloc is what is known as an "exception". To use exceptions, you need to use a try ... catch block. If an error is encountered, you "throw" (not return) an exception. The exception is then caught by the appropriate catch block. Some functions, such as new, automatically throw them for you.

Some basic information.

Edited 6 Years Ago by Fbody: n/a

Comments
Clear and concise.

So I saw :

// bad_alloc example
#include <iostream>
#include <new>
using namespace std;

int main () {
  try
  {
    int* myarray= new int[10000];
  }
  catch (bad_alloc& ba)
  {
    cerr << "bad_alloc caught: " << ba.what() << endl;
  }
  return 0;
}

What is the catch (bad_alloc& ba) about? Would I need that exact line even if I didn't want to be able to say what the bad_alloc was? i.e. I only want it to say "Can't allocate!" rather than "bad_alloc caught: bad allocation"

Sorry if this is tedious for you guys.

Ed

You would need both the try and the catch. The catch must be formatted to catch a thrown bad_alloc. This is what the "bad_alloc& ba" part does. It tells the compiler that it's intended to catch a bad_alloc exception. When it catches one, it will be referred to as "ba" inside the "handler".

If you don't catch the bad_alloc, the program will crash/terminate with an "Unhandled Exception" error.

The contents of the catch statement block can be pretty-much whatever you like. The critical part is the catch itself.

I don't like the example given. I thisk that it misses the opportunity to be a useful learning tool: I would like it modified like this to allow the user to actually see what went on:

// bad_alloc example [+ modification]
#include <iostream>
#include <new>

int main () 
{
  long int allocateSize(1);
  for(int i=0;i<100;i++)
    {
      allocateSize*=10;
      try
	{
	  std::cout<<"Before allocation :"<<allocateSize<<std::endl;
	  int* myarray= new int[allocateSize];
	  std::cout<<"After allocation :"<<allocateSize<<std::endl;
          std::cout<<"--------"<<std::endl;
	  delete [] myarray;
	}
      catch (std::bad_alloc& ba)
	{
	  std::cout << "bad_alloc caught: " << ba.what() << std::endl;
	  std::cout << "Allocation size == "<<allocateSize<<std::endl;
	  return -1;
	}
    }
  std::cout<<"This is computer has a HUGE memory system"<<std::endl;
  return 0;
}

So run the code and see if you are surpised by the observation that you see the last before message but not the after message, NOR the last message.

However, take out the return -1 and observer that you see MANY bad allocates, as the loop completes.

Edited 6 Years Ago by StuXYZ: n/a

Thanks again for the responses.
I have one last question; is the #include <new> needed? I don't have it in my code at the moment, and it's able to use the new operator successfully. I'm just wondering what it adds.

Thanks again.

Ed

It adds bad_alloc.

Yes, some compilers have it in iostream, [including gcc] but if you were to remove the std::cout part then new is the file that it is actually declared in.

The #define _NEW ... #endif around the file will limit the compiler overhead from re-compiling the file. [obviously doesn't completely eliminate it]

Edited 6 Years Ago by StuXYZ: n/a

This article has been dead for over six months. Start a new discussion instead.