0

What's the difference between new _Elem[_Size]() vs. new _Elem[_Size]{} and which form should I prefer ?

Does it make a difference if you know the element in question and it's not used on template parameter ?

This question assumes that a raw pointer is needed - normally you should just use a std::vector or std::unique_ptr

darune
  • 10,480
  • 2
  • 24
  • 62
  • In C++11 and later, both dynamically allocate an array of `_Size` elements of type `_Elem`. If `_Elem` has a constructor that accepts an initialiser list, that is used in the second case, but default initialisation is used in the first. In other cases the two are equivalent. – Peter Apr 11 '19 at 09:36
  • 1
    @Peter - It's only used in the second case if there is no default constructor. If a default constructor is present, both forms do the same thing. But it's moot anyway, since this Q is about the array new expression. – StoryTeller - Unslander Monica Apr 11 '19 at 09:48

2 Answers2

2

There is no difference between the two.

Except the {} one doesn't work in C++98.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
2

In C++ the {} is used to provide an initialisation value to the object, and has been implemented since C++03.

Here is some useful information about value inizialization:
https://en.cppreference.com/w/cpp/language/value_initialization
and a forum post asking a very similar question with a good answer by a user called Alok Save:
What does 'value initializing' something mean?

Which you should use depends on what you will do with the object, and whether its constructors accept value initialization. After C++03, if an array of objects is being created and you put data within {} and the object's constructor accepts value initialization, each element of the array will be value-initialized, but if you just put{}, the array will be zero-initialized if this is supported.
For example, here are various ways to initialize an array of integers:

To value-initialize the list do this:
int* intArray = new int[5]{1, 2, 3, 4, 5};
And the list will be initialized as this:
1, 2, 3, 4, 5

But if you try and initialize the list like this:
int* intArray = new int[5]{1};
You will end up with:
1, 0, 0, 0, 0
This is because for integer arrays, an initializer value is expected for each element.

Also note that by using the default constructor, the list is not initialized at all (for integer lists, anyway), so this:
int* intArray = new int[5];
Will result in each element retaining whatever value is already at that memory location, such as:
16256696, 16253120, 0, 0, -1543503708
If the first thing you plan to do is to populate the array with data from your program, this is faster and more efficient as you don't have to set the data in each memory location twice. However as pointed out in the comments, this ultimately means that the data in your array WILL be unpredictable, so you need to be sure you are populating the whole array as soon as possible to prevent potential bugs.

Alternatively if you want that data to be zero-initialized you should do the following:
int* intArray = new int[5]{};
And the list qill be initialized as:
0, 0, 0, 0, 0

However, there is no guarantee that this will be the same for the _Elem data type, so I'd recommend doing some testing similar to what I have done here to figure out what is most relevant for you.

  • I believe that `int* intArray = new int[5];` expressions should be avoided even if you plan to fill it immediately - as it opens a window for one of the worst classes of bugs. If you ever have a situation with this case and where the performance makes any difference - then you should probably already know what you are doing. – darune Apr 11 '19 at 14:28
  • 1
    @darune It's ultimately up to them to decide which is most suitable, I simply included it as a demonstration of one of the ways it can be done. Ultimately it depends where it is to be implemented and how critical speed is. It may not save much time on it's own, but for programs which run over many iterations it could be beneficial to save that tiny amount of time. – NathanielJS Apr 11 '19 at 14:35
  • @darune I shall edit the answer to reflect the potential consequences of doing this, so thanks for the suggestion. – NathanielJS Apr 11 '19 at 14:36