initialization - How to initialise memory with new operator in C++?

ID : 20352

viewed : 19

Tags : c++initializationmemory-managementnew-operatorc++

Top 5 Answer for initialization - How to initialise memory with new operator in C++?

vote vote

97

It's a surprisingly little-known feature of C++ (as evidenced by the fact that no-one has given this as an answer yet), but it actually has special syntax for value-initializing an array:

new int[10](); 

Note that you must use the empty parentheses — you cannot, for example, use (0) or anything else (which is why this is only useful for value initialization).

This is explicitly permitted by ISO C++03 5.3.4[expr.new]/15, which says:

A new-expression that creates an object of type T initializes that object as follows:

...

  • If the new-initializer is of the form (), the item is value-initialized (8.5);

and does not restrict the types for which this is allowed, whereas the (expression-list) form is explicitly restricted by further rules in the same section such that it does not allow array types.

vote vote

88

There is number of methods to allocate an array of intrinsic type and all of these method are correct, though which one to choose, depends...

Manual initialisation of all elements in loop

int* p = new int[10]; for (int i = 0; i < 10; i++)     p[i] = 0; 

Using std::memset function from <cstring>

int* p = new int[10]; std::memset(p, 0, sizeof *p * 10); 

Using std::fill_n algorithm from <algorithm>

int* p = new int[10]; std::fill_n(p, 10, 0); 

Using std::vector container

std::vector<int> v(10); // elements zero'ed 

If C++11 is available, using initializer list features

int a[] = { 1, 2, 3 }; // 3-element static size array vector<int> v = { 1, 2, 3 }; // 3-element array but vector is resizeable in runtime 
vote vote

78

Assuming that you really do want an array and not a std::vector, the "C++ way" would be this

#include <algorithm>   int* array = new int[n]; // Assuming "n" is a pre-existing variable  std::fill_n(array, n, 0);  

But be aware that under the hood this is still actually just a loop that assigns each element to 0 (there's really not another way to do it, barring a special architecture with hardware-level support).

vote vote

65

Yes there is:

std::vector<int> vec(SIZE, 0); 

Use a vector instead of a dynamically allocated array. Benefits include not having to bother with explicitely deleting the array (it is deleted when the vector goes out of scope) and also that the memory is automatically deleted even if there is an exception thrown.

Edit: To avoid further drive-by downvotes from people that do not bother to read the comments below, I should make it more clear that this answer does not say that vector is always the right answer. But it sure is a more C++ way than "manually" making sure to delete an array.

Now with C++11, there is also std::array that models a constant size array (vs vector that is able to grow). There is also std::unique_ptr that manages a dynamically allocated array (that can be combined with initialization as answered in other answers to this question). Any of those are a more C++ way than manually handling the pointer to the array, IMHO.

vote vote

54

If the memory you are allocating is a class with a constructor that does something useful, the operator new will call that constructor and leave your object initialized.

But if you're allocating a POD or something that doesn't have a constructor that initializes the object's state, then you cannot allocate memory and initialize that memory with operator new in one operation. However, you have several options:

  1. Use a stack variable instead. You can allocate and default-initialize in one step, like this:

     int vals[100] = {0}; // first element is a matter of style 
  2. use memset(). Note that if the object you are allocating is not a POD, memsetting it is a bad idea. One specific example is if you memset a class that has virtual functions, you will blow away the vtable and leave your object in an unusable state.

  3. Many operating systems have calls that do what you want - allocate on a heap and initialize the data to something. A Windows example would be VirtualAlloc().

  4. This is usually the best option. Avoid having to manage the memory yourself at all. You can use STL containers to do just about anything you would do with raw memory, including allocating and initializing all in one fell swoop:

     std::vector<int> myInts(100, 0); // creates a vector of 100 ints, all set to zero 

Top 3 video Explaining initialization - How to initialise memory with new operator in C++?

Related QUESTION?