I'm just beginning to get into C++ and I want to pick up some good habits. If I have just allocated an array of type int
with the new
operator, how can I initialise them all to 0 without looping through them all myself? Should I just use memset
? Is there a “C++” way to do it?

- 93,976
- 29
- 161
- 209
-
20If you want to pickup a good C++ habit, then avoid using arrays directly and use vector instead. Vector will initialize all the items regardless of the type, and then you don't need to remember to call the delete[] operator. – brianegge Feb 05 '10 at 00:37
-
@brianegge: What if I need to pass an array to an external C function, can I just give it the vector? – dreamlax Feb 05 '10 at 01:28
-
12You can pass `&vector[0]`. – jamesdlin Feb 05 '10 at 01:54
-
Of course, when you pass arrays to C functions, you typically have to specify the pointer to the first element, &vector[0] as @jamesdlin said, and the size of the array, provided in this case by vector.size(). – Trebor Rude Mar 25 '14 at 20:39
-
Related (asks for non-array types): https://stackoverflow.com/questions/7546620/operator-new-initializes-memory-to-zero – Aconcagua Nov 19 '18 at 07:08
10 Answers
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.

- 1
- 1

- 99,783
- 25
- 219
- 289
-
2While I agree that this is little-known, I can't (entirely) agree that it's really very surprising -- it was added in C++ 03, which most people seem to have nearly ignored (since this was one of the few new things it did add). – Jerry Coffin Feb 05 '10 at 03:14
-
2@Jerry: I must admit that I didn't knew yet (probably because when I got to reading the standard, it was C++03 already). That said, it's remarkable that all implementations I know of support this (I guess it's because it's so trivial to implement). – Pavel Minaev Feb 05 '10 at 03:28
-
3Yes, it is pretty trivial to implement. As far as being new, *all* "value initialization" was new in C++ 03. – Jerry Coffin Feb 05 '10 at 04:01
-
50In C++11 you can use uniform initializtion as well: `new int[10] {}`. You can also provide values to initialize with: `new int[10] {1,2,3}` – bames53 Aug 13 '13 at 18:13
-
1Please don't confuse default-initialized with value-initialized: They are both clearly defined in the standard and are different initializations. – Deduplicator Oct 05 '14 at 16:45
-
Also see [Are () and {} always equivalent when used for initialization with "new"?](https://stackoverflow.com/questions/30012733/are-and-always-equivalent-when-used-for-initialization-with-new) and [What do the following phrases mean in C++: zero-, default- and value-initialization?](https://stackoverflow.com/questions/1613341/what-do-the-following-phrases-mean-in-c-zero-default-and-value-initializat) – Laurie Stearn Dec 01 '22 at 19:43
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

- 44,692
- 7
- 66
- 118

- 37,086
- 11
- 109
- 136
-
1should be vector
If you added p= new int[10]() you had a complete list. – karsten Jan 20 '17 at 09:44 -
@mloskot, in the first case where you have initialized an array using "new", how pass by reference will happen? If I used `int array[SIZE] ={1,2,3,4,5,6,7};` notation, I can use `void rotateArray(int (& input)[SIZE], unsigned int k);` would be my function declaration, what would be when using the first convention? any suggestion? – Anu Jan 28 '19 at 16:50
-
2I am afraid the example with `std::memset` is wrong - you pass 10, it seems to expect number of bytes - see https://en.cppreference.com/w/cpp/string/byte/memset. (I think this nicely shows why should one avoid such low-level construct when possible.) – Suma Dec 03 '19 at 14:45
-
@Suma Great catch! Fixed. This seems to be a candidate for a decade old bug :-) Yes, I agree with your comment. – mloskot Dec 04 '19 at 15:40
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).

- 74,820
- 18
- 121
- 166
-
I don't mind if the loop is implemented underneath a function, I just wanted to know whether or not I had to implement such a loop myself. Thanks for the tip. – dreamlax Feb 05 '10 at 00:10
-
4You might be surprised. I was. On my STL (both GCC and Dinkumware), std::copy actually turns into a memcpy if it detects it is being called with built in types. I wouldn't be surprised if std::fill_n used memset. – Brian Neal Feb 05 '10 at 01:12
-
2
-
Possible ways of initializing the plain dyanmic array. Choose the one as per your requirement.
int* x = new int[5]; // gv gv gv gv gv (gv - garbage value)
int* x = new int[5](); // 0 0 0 0 0
int* x = new int[5]{}; // 0 0 0 0 0 (Modern C++)
int* x = new int[5]{1,2,3}; // 1 2 3 0 0 (Modern C++)

- 8,481
- 2
- 52
- 43
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:
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
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.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()
.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

- 44,692
- 7
- 66
- 118

- 99,718
- 31
- 186
- 324
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.

- 8,540
- 6
- 45
- 76
-
11
-
1Should I always use `std::vector` instead of dynamically allocated arrays? What are the benefits of using an array over a vector, and vice versa? – dreamlax Feb 05 '10 at 00:11
-
I should have mentioned in my question, that the array must persist after the current scope. Do I have to use `new std::vector`? – dreamlax Feb 05 '10 at 00:14
-
1@John Knoller: The OP asked about a C++ way to do it, I'd say that vector is the c++ way to do this. Of course, you are correct that there might be situations that still would call for a plain array and not knowing the OP's situation this might be one. I'd guess no though, since it seems plausible that the OP does not know about vectors. – villintehaspam Feb 05 '10 at 00:16
-
An array is somewhat faster, you control it fairly tightly. OTOH, you have to manage freeing the memory. When interfacing with C, sometimes you have to pass C functions an array. For most situations, vector is all you need. – Paul Nathan Feb 05 '10 at 00:16
-
@dreamlax: If it must persist after the scope, I would still prefer using a vector instead of an array. Only I would wrap it in a shared_ptr to make sure that it gets deleted. Using a shared_array is another option if you really must use a real array. (for a description of shared_ptr/shared_array, see www.boost.org). – villintehaspam Feb 05 '10 at 00:21
-
1@villintehaspam: Although this solution doesn't answer my question it is the path I am going to take. Tyler McHenry answers my question more directly, and should help especially for people who cannot—for whatever reason—use `std::vector`. – dreamlax Feb 05 '10 at 00:33
-
@villintehaspam: what if you are the guy writing std:vector? what do you do then? _someone_ has to do the job rather than just punting it into a library. – John Knoeller Feb 05 '10 at 00:41
-
@John Knoeller: as I've pointed out many times before, you do NOT use a dynamically allocated array to implement `std::vector`. You use `::operator new` to allocate memory, and placement new to create objects in that memory -- it's substantially different, and `new[]` simply won't work (e.g., it immediately creates objects in all the memory allocated, which `std::vector` can't do). – Jerry Coffin Feb 05 '10 at 00:52
-
@Jerry: std::vector sure as hell doesn't use _stack_ allocation or _const_, so it must be dynamic allocation at some level. if the answer dreamlax's question is that new[] automatically inits the array, then it would be nice if someone actually _said_ that instead of deflecting. – John Knoeller Feb 05 '10 at 00:58
-
2@villintehaspam: No, it is not a C++ way to do it. It is Java way to do it. Sticking `vector` everywhere regardless of context is called "Writing Java code in C++". – AnT stands with Russia Feb 05 '10 at 01:02
-
@John Knoeller: I was very specific in saying it doesn't use a dynamically allocated *array*. I already talked about what it does to allocate storage. The bottom line is that there's almost never any reason to use `new[]` -- even if you are the one implementing `std::vector` or something similar. – Jerry Coffin Feb 05 '10 at 01:13
-
@Jerry: Ok, I'll accept that. I've never had any use for new[], but I thought that was just me. – John Knoeller Feb 05 '10 at 01:15
-
1@AndreyT: I agree that _always_ using vector over a dynamic allocated array isn't a good statement. However I would still argue that using a vector over a dynamically allocated array is the C++ way to do it and it should definitely be the preferred choice unless there is some particular reason to use a dynamically allocated array. This isn't writing Java code, it is getting the job done with minimal effort and lower risk of errors. – villintehaspam Feb 05 '10 at 09:24
std::fill
is one way. Takes two iterators and a value to fill the region with. That, or the for loop, would (I suppose) be the more C++ way.
For setting an array of primitive integer types to 0 specifically, memset
is fine, though it may raise eyebrows. Consider also calloc
, though it's a bit inconvenient to use from C++ because of the cast.
For my part, I pretty much always use a loop.
(I don't like to second-guess people's intentions, but it is true that std::vector
is, all things being equal, preferable to using new[]
.)
you can always use memset:
int myArray[10];
memset( myArray, 0, 10 * sizeof( int ));

- 7,659
- 38
- 59
-
I understand that I can use `memset`, but I wasn't sure if this was the C++ way to approach the problem. – dreamlax Feb 05 '10 at 00:15
-
Yup, memset works just as well in C++ as in C for setting linear memory to a value. – Gregor Brandt Feb 05 '10 at 00:18
-
1It's not really the 'the C++ way', but then neither are raw arrays. – Pete Kirkham Feb 05 '10 at 00:21
-
@gbrandt - while that may be true, I wouldn't say it's "the C++ way". There are more "accepted" ways of doing it. – Smashery Feb 05 '10 at 00:21
-
1@gbrandt:Which is to say that it doesn't work very well in either C or C++. It works for most values of the type is char or unsigned char. It works for most types of the value is 0 (at least in most implementations). Otherwise, it's generally useless. – Jerry Coffin Feb 05 '10 at 00:48
-
1`10 * sizeof( *myArray )` is more documented and change-proof than `10 * sizeof( int )`. – Kevin Reid Feb 05 '10 at 01:04
-
1In any case, the OP has a raw array and memset is the fastest and easiest way to zero that array. – Gregor Brandt Feb 05 '10 at 03:43
For c++ use std::array<int/*type*/, 10/*size*/>
instead of c-style array. This is available with c++11 standard, and which is a good practice. See it here for standard and examples. If you want to stick to old c-style arrays for reasons, there two possible ways:
int *a = new int[5]();
Here leave the parenthesis empty, otherwise it will give compile error. This will initialize all the elements in the allocated array. Here if you don't use the parenthesis, it will still initialize the integer values with zeros because new will call the constructor, which is in this caseint()
.int *a = new int[5] {0, 0, 0};
This is allowed in c++11 standard. Here you can initialize array elements with any value you want. Here make sure your initializer list(values in {}) size should not be greater than your array size. Initializer list size less than array size is fine. Remaining values in array will be initialized with 0.
-
The size for `std::array<>` must be known at compile-time. It is not possible to declare `std::array<>` based on a size determined at runtime, so it is not always practical or possible to use `std::array<>` over `new[]` or `std::vector<>`. – dreamlax Feb 19 '21 at 07:18
-
@dreamlax yes totally agree with you. We can use only fixed size array with std::array<> whose size must be known at compile time. – Neeraj C. Usadadiya Feb 19 '21 at 07:34
Typically for dynamic lists of items, you use a std::vector
.
Generally I use memset or a loop for raw memory dynamic allocation, depending on how variable I anticipate that area of code to be in the future.

- 39,638
- 28
- 112
- 212