Search code examples
c++exceptionpointersconstructordynamic-memory-allocation

Try/catch block for simple memory allocation into public raw pointer when inside constructor?


I have a case with a raw pointer that I can't change to a smart pointer because it is part of the interface (and I don't want to break any code using it):

struct Foo
{
  Foo();
  ~Foo();

  int * m_pStuff; // public!
};

I don't want to do much in my ctor. Just something like:

m_pStuff = new int[dynamically_obtained_size_which_is_greater_than_0];
m_pStuff[0] = 0;

And then in the destructor delete it.

Now, I wonder if it's really worth surrounding it with a try/catch:

Foo::Foo()
  : m_pStuff(0)
{
  try
  {
    m_pStuff = new int[dynamically_obtained_size_which_is_greater_than_0];
    m_pStuff[0] = 0;
  } 
  catch(...)
  {
    delete m_pStuff;
    throw;
  }
}

Points I can see against:

  • More complex code
  • Not really expecting any exception to happen there (unless it run out of space when allocating)
  • Not really expecting the code to change

Points I can see for:

  • Indicates to potential future coders that they should be careful with anything throwing exceptions and put it in the try block that is already in place
  • If any exception does happen, memory release is taken care of

I am quite undecided: should I surround this with a try/catch or not? Why? I would like to get your opinions on that.

Also, do you see any possibility of exception other then resulting from out of memory when allocating? And in that case the already allocated memory would be automatically reclaimed, right?

Thanks!


Solution

  • No.

    It's completely pointless.

    int construction may not throw, so the only possible exception here is a std::bad_alloc. What are you doing in this case?

    • Well, first you're doing delete on a NULL pointer, which is a no-op. The allocation failed, so you're not "reclaiming" anything.
    • Then you're rethrowing the exception.

    i.e. precisely what happens without the try/catch.

    Just let the exception propagate, and document that it is possible.

    This advice does not necessarily apply to other types, though.


    Also, don't forget your copy constructor.