0

I read allready about some ways like doing this for known amount of values like:

new int[3] {0 , 0, 0};

After this remembered me of the way of initializing arrays on declaration in C I asked my self about it is also valid in C++ to do this:

new int[n] {}

Where the empty Braces cause everything to be 0-initialized. After trying out it looks fine to me, but could also just be caused by randomness and in real UB or something.

And if it is valid, are there also ways to init on a specific value?

note:

I want to achieve the same as a call to calloc (n, sizeof(int)); would do. But since I'm now in C++ and not C anymore I won't use theese functions anymore to keep the code readable.

note2:

When saying

I want to achieve [...]

It is corresponding to my minimal example, at all I just want to obtain a zero initialized block of valid memory.

dhein
  • 6,431
  • 4
  • 42
  • 74
  • 4
    why not to use `std::array` or `std::vector` ? – Slava Jul 15 '15 at 12:48
  • Is `n` of type `const`? – yizzlez Jul 15 '15 at 12:48
  • @Slava because this is an minimal example and I simply need an zero intialized memory block, not any vector or array implementation... – dhein Jul 15 '15 at 12:49
  • @awesomeyi: nope, it is different when ever the scope of that `new` is entered. – dhein Jul 15 '15 at 12:50
  • Must... not... say... calloc. – Mr Lister Jul 15 '15 at 12:53
  • @Zaibis "I simply need an zero intialized memory block" is controversial to "are there also ways to init on a specific value?", is it not? – Slava Jul 15 '15 at 12:54
  • @MattMcNabb: Mr Lister: ofc thats what I'm looking for, see my note. – dhein Jul 15 '15 at 12:57
  • See also [this earlier answer](http://stackoverflow.com/a/9603834/15416) - almost a duplicate IMO. – MSalters Jul 15 '15 at 13:09
  • @MSalters: it isn't I read that before and my question is: if that is possible, is doing `int[n] {}` (expect the `n`) also valid as it is in plain `C` and if not is there another way to do it? – dhein Jul 15 '15 at 13:13
  • @zaibis: If it's minimal then you don't want to litter it with hard complex things like actual safety. – Puppy Jul 15 '15 at 13:19
  • @Zaibis Even if this is a simplified example you should use `std::vector` in real code. Really. Don’t use `new`. Need a buffer? Use `std::vector`. Need a buffer and *really, **really** cannot deal with the overhead of a `std::vector` (which is practically nonexistent)? Use an allocator (and wrap it inside a smart pointer, or use `std::unique_ptr` directly). Don’t use `new`. – Konrad Rudolph Jul 15 '15 at 13:31
  • @Zaibis: Well, C doesn't have constructors or `new [ ]` so there's no _direct_ comparison. But for array initializers in C++, missing elements are value-initialized (i.e. default constructor for class types and 0 for built-in types). – MSalters Jul 15 '15 at 13:34

4 Answers4

4
auto array = new int[n] ();

This performs zero initialisation, since int is a "non class type".

auto array = new int[n];

This doesn't. The initial values are indeterminate. Note though that the background behind this is very confusing and the description in the standard changed a few times, probably to make it less confusing, which IMHO failed to achieve its effect. Some relevant links therefore:

(Do also read the comments)

[...] I simply need an zero intialized memory block, not any vector or array implementation...

std::vector is a simple memory block. Use it. The additional member functions that are provided by it have no cost unless you use them. There won't be any resizing if you don't need it. Use it for the same reasons that you should prefer std::unique_ptr or std::shared_ptr over a raw pointer whenever possible!

Community
  • 1
  • 1
Daniel Jour
  • 15,896
  • 2
  • 36
  • 63
1

I would not use new operator and use C++ STL containers such as std::vector or std::array. Here a small example since you know the size at compile time :

std::array<int,3> foo{}; // will initialize a std::array with 0 value.

For some more explanations about the initialization :

new int[5] () is zero initialization it is valid and initialize elements to 0.

2) As part of value-initialization sequence for non-class types and for members of value-initialized class types that have no constructors.

new int[5] is default initialization you are not guaranteed about it, since the values are filled arbitrary.

If T is an array type, every element of the array is default-initialized.

coincoin
  • 4,595
  • 3
  • 23
  • 47
  • this is confusing me. I read so far in the standard that the difference between `new` with and without `()` is that with them it is default initialized and without it isnt. But I couldn't figgure out what "default initialized" means. not even in the standard document it self (ofcourse it is in their but I wasn't able to find) – dhein Jul 15 '15 at 12:57
  • Hum I will modify my answer according to this : http://en.cppreference.com/w/cpp/language/default_initialization – coincoin Jul 15 '15 at 13:02
  • I would. The OP asked for a minimal example, and stated his intention to keep things simple; however, you replied with code that would require a massive amount of difficult and repetitive error-handling to use safely. – Puppy Jul 15 '15 at 16:32
  • Thanks for your comment. Indeed I have focused on the explanation between the two implementations. I did not see that OP wanted a "good practice to do it". I therefore added my advice. – coincoin Jul 15 '15 at 17:55
0

Simply writing new int[n] just allocates memory and initializes nothing, so given bytes still have values from another usage in past which is unknown.

With adding brackets, C++ adds a construction and fills empty fields with zero.

For more, read this.

Youka
  • 2,646
  • 21
  • 33
  • Is the source you refer really about c++? It looks like plain C to me as it is refering to c99 and `VLA`'s which afaik aren't even valid in `c++` – dhein Jul 15 '15 at 13:11
  • @Zaibis Good point. Most of C99 features were adopted to C++, including simple forms of array initialization. To be more clear, i refer to the relevant C++ documents [default initialization](http://en.cppreference.com/w/cpp/language/default_initialization) and [direct initialization](http://en.cppreference.com/w/cpp/language/direct_initialization). Since C++11 there're even [list initialization](http://en.cppreference.com/w/cpp/language/list_initialization) which can be used for PODs too. – Youka Jul 15 '15 at 13:25
0

You can use std::vector.

std::vector<int> x(5);

The main advantage here is that std::vector is actually safe, unlike new.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • What do you mean by safe? – dhein Jul 15 '15 at 13:27
  • I mean that if you want to use `new` in a fashion that won't leak memory, double delete memory, use memory after being freed, corrupt heap, etc, this is virtually impossible for any non-trivial program and doing so requires a whole bunch of very complicated exception safety and related matters, which is decidedly not simple at all. The `std::vector` guys already implemented it for you, making your program much *simpler*. – Puppy Jul 15 '15 at 16:23