Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to initialize dynamic Array in C++

I'm currently working on a C++ project, where dynamic arrays often appear. I was wondering, what could be the correct way to initialize a dynamic array using the new-operator? A colleague of mine told me that it's a no-no to use new within the constructor, since a constructor is a construct that shouldn't be prone to errors or shouldn't fail at all, respectively. Now let's consider the following example: We have two classes, a more or less complex class State and a class StateContainer, which should be self-explained.

class State {
private:
 unsigned smth;
public:
 State();
 State( unsigned s );
};

class StateContainer {
private:
 unsigned long nStates;
 State *states;
public:
 StateContainer();
 StateContainer( unsigned long n );
 virtual ~StateContainer();
};

StateContainer::StateContainer() {
 nStates = SOME_DEFINE_N_STATES;
 states = new State[nStates];
 if ( !states ) {
  // Error handling
 }
}

StateContainer::StateContainer( unsigned long n ) {
 nStates = n;
 try {
  states = new State[nStates]
 } catch ( std::bad_alloc &e ) {
  // Error handling
 }
}

StateContainer::~StateContainer() {
 if ( states ) {
  delete[] states;
  states = 0;
 }
}

Now actually, I have two questions:

1.) Is it ok, to call new within a constructor, or is it better to create an extra init()-Method for the State-Array and why?

2.) Whats the best way to check if new succeeded:

if (!ptr) std::cerr << "new failed."

or

try { /*new*/ } catch (std::bad_alloc) { /*handling*/ } 

3.) Ok its three questions ;o) Under the hood, new does some sort of

ptr = (Struct *)malloc(N*sizeof(Struct));

And then call the constructor, right?

like image 314
mefiX Avatar asked Apr 30 '10 07:04

mefiX


1 Answers

You should let the std::bad_alloc propagate - there's likely nothing reasonable you could do anyway.

First of all, throwing an exception from the constructor is the only reliable way to signal a problem - if there's no exception it means the object is completely constructed. So catching std::bad_alloc alone will not help against other possible exceptions.

Then what can you do to "handle" it in such a way that the other code is aware and can react appropriately?

Use exceptions right - let them propagate to the site where they can be reasonably handled.

like image 77
sharptooth Avatar answered Sep 23 '22 22:09

sharptooth