2
int n[] = {1000,5000,100000,105000,400000,500000,505000,800000,995000,1000000};

int *array1 = new int[n[0]]; //1000
int *array2 = new int[n[1]]; //5000

Is this valid for creating array1 size 1000 and array2 size 5000?

Even after programming for a year this stuff still trips me up.

And my second question: Is there any way to automatically set all values in each position to NULL or 0? Because after printing the array, the first chunk of numbers are:

1163089152
1330794578
1162627398
1547322173
1919251285
1766218867
7367020
1129595223
1128090959
1635212346
1836016500
1852405504
1030908260
1465662019
1868852841
29559
1625020798
134224442
4199212
4234532
4234544
4209436
4200378
4286800
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1910233198
134224636
1985292544
1985292576
1985292608
1985292640
1985292672
1985292704
1985292736
1985292768
1985292800
1985292832
1985292864
1985292896
1985292928
1985292960
1985292992
1985293024
1985293056
1985293088
1985293120
1985293152
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0 

... .... .....

And in my current assignment efficiency is key. Looping through 1000 elements just to set them to 0 or NULL seems...inefficient

EDIT: Problem solved, thank you all for the speedy answers!

user3507072
  • 287
  • 1
  • 4
  • 13

6 Answers6

9
  1. Yes, it is a valid way to allocate that memory
  2. No, the values aren't initalized to any specific values. You can value* initialize them if you desire:

    int *array1 = new int[n[0]](); // Introduced in C++98
    int *array1 = new int[n[0]]{}; // Introduced in C++11
    

That will initialize all values to zero.

*"default initialization" in this context is a colloquial misnomer for "value initialization", which was introduced in C++03 and is almost always what is meant when one says "default initialization".

Community
  • 1
  • 1
Cornstalks
  • 37,137
  • 18
  • 79
  • 144
  • I believe C++98 did not support value initialized `operator new[]` – Slava Oct 14 '14 at 15:49
  • 1
    You can write `new int[n[0]]()` in C++11 as well. :P – Nawaz Oct 14 '14 at 15:52
  • Also, **none** of the syntaxes uses "default" initialization. They're "value" initializations. And there is a huge difference. – Nawaz Oct 14 '14 at 15:54
  • @Nawaz: I know, I wasn't trying to say you couldn't do that. What I was trying to show is syntax that different versions of the C++ standard introduced. C++98 introduced `()`, C++11 introduced `{}`. And I know they're value initializations. That's why I said "value" first in "value/default initializations". Many of the people I've talked to say "default initialize" though, so I included that term as it's more easily understood by many of the people I've talked to. A misnomer, sure, but colloquial none the less. – Cornstalks Oct 14 '14 at 15:55
  • All I meant, if you're writing "value/default" initialization, you're being incorrect, or at least imprecise and confusing. – Nawaz Oct 14 '14 at 15:56
  • @Cornstalks "C++98 introduced ()" did it? I believe it did not, that was a non standard extension for some compilers. – Slava Oct 14 '14 at 16:09
  • @Slava: I've been trying to find a copy of the C++98 standard but can't find one. I suppose it's possible C++03 introduced it, but I had always been under the impression it was available before C++03. If you find/have a copy of the C++98 standard, let me know, as I'd be curious to dig into this more to double check. Clang/GCC accepts it in C++98 mode, though that's hardly an authoritative proof. – Cornstalks Oct 14 '14 at 16:10
  • http://en.wikipedia.org/wiki/New_(C%2B%2B) "In C++98 initializers cannot be specified for arrays created with new." – Slava Oct 14 '14 at 16:14
  • @Cornstalks I found ISO/IEC 14882:1998 here http://sites.cs.queensu.ca/gradresources/stuff/cpp98.pdf – Slava Oct 14 '14 at 16:17
  • @Nawaz: I added some notes; it is better? – Cornstalks Oct 14 '14 at 16:18
  • @Slava: Thanks! I'm digging into those now. – Cornstalks Oct 14 '14 at 16:19
  • @Slava: You're reading the wiki-entry **incorrectly**. C++98 doesn't allow this : `int *x = new int[3] {1,2,3};` which is the wiki-text meant. – Nawaz Oct 14 '14 at 16:23
  • @Slava: 5.3.4 says the syntax `new [([expression list])]` is valid (where the things in `[]` are optional), so it indeed appears that `new int[5] ()` is acceptable, and paragraph 15 says that default initialization will be done according to 8.5. – Cornstalks Oct 14 '14 at 16:25
  • @Cornstalks: Just remove the incorrect part. Just because there are programmers who use this term (default-initialization) in this (incorrect) way, doesn't mean we should continue doing that on this site. It is the time when you can correct things. – Nawaz Oct 14 '14 at 16:26
  • @Cornstalks strange, I had that in my memory that it is not, probably I was mistaken – Slava Oct 14 '14 at 16:52
3

Yes, it's fine, but if you want the array data to be initialised to zero then you need:

int *array1 = new int[n[0]]();
int *array2 = new int[n[1]]();
                          ^^^^

You might want to consider using slightly more up-to-date C++ idioms though - std::vector would probably be a better choice than raw arrays:

std::vector<int> array1(n[0]);
std::vector<int> array2(n[1]);
Paul R
  • 208,748
  • 37
  • 389
  • 560
3
  1. Yes, it's valid.
  2. It's uninitalized. To initialize the elements to 0, use

     int *array1 = new int[n[0]]();
     //                         ^^
    
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
3

Is this valid for creating array1 size 1000 and array2 size 5000?

Yes, it is valid, because you are using operator new[]. If you declared int array1[n[0]], you would be relying on an extension, because variable-length arrays are not supported in C++.

Will all array positions be set to NULL or 0?

Neither. The values will be undefined (that's a fancy way of saying "garbage") until you assign to them. You can force initialization by appending a pair of parentheses after the call of new[].

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

Yes operator new[] is doing dynamic memory allocation and it is valid to pass a value whatever way you get it. No value will not be initialized and you should not forget to call delete[] for that pointer or use a smart pointer.

Better way would be to use std::vector -

std::vector<int> array1( n[0] );
std::vector<int> array2( n[1] );

you do not need to worry on memory deallocation and data will be initialized. If you need to initialize some different value than 0, just pass it as a second parameter:

std::vector<int> array1( n[0], 123 );
std::vector<int> array2( n[1], 456 );
Slava
  • 43,454
  • 1
  • 47
  • 90
  • If I maintain variable names array1, wouldn't it be better to use arrays instead of vectors? Because after freeing, I can store whatever I want into that array again. But with vectors, there is no free statement? – user3507072 Oct 14 '14 at 15:49
  • @user3507072: No, you can't use an array after freeing it. It no longer exists. – Mike Seymour Oct 14 '14 at 15:52
  • Correct, but another declaration and initialization of the array solves this. Are you implying that vectors automatically free the old version when re-declared? – user3507072 Oct 14 '14 at 15:53
  • @user3507072: I've no idea what you mean. You can't declare the pointer a second time. You could reassign it to point to a newly allocated array, just as you could reassign (or resize) a vector. – Mike Seymour Oct 14 '14 at 15:57
  • @user3507072 to start with `free()` goes with `malloc()` not `new` (you're looking for `delete[]`). With vectors, all the memory management is done for you; vector goes out of scope, and destructors are called automatically. You can change the data in a `vector` as easilly as in an `array` but you can't use either once deleted or out of scope, and finally, you can call the variables whatever you want, `std::vector supercalifragilisticexpealidocious` if you wish. Call it whatever is suitable for the problem. – Baldrickk Oct 14 '14 at 15:58
  • @user3507072 you messed up. If you define vector as a local variable it will free up the memory when it is going out of scope. Of course you can create vector with the same name somewhere else. It is like any other variable. Or you can resize/reinitilize existing vector (if it is global for example) if you do not want additional memory operations. – Slava Oct 14 '14 at 15:59
1

Is this valid for creating array1 size 1000 and array2 size 5000?

Yes. But you'll be better off using automatically managed dynamic arrays:

std::vector<int> array1(1000);

to save yourself the bother of remembering to delete the array once you've finished with it. It can be surprisingly difficult to get that right without RAII.

Will all array positions be set to NULL or 0?

No. new will default-initialise the objects it creates; in the case of primitive types like int, default-initialisation doesn't do anything, leaving them with indeterminate values.

If you want them to be value-initialised to zero, then you can specify that:

int *array1 = new int[n[0]]();
                           ^^

or use vector, which will value-initialise them unless you specify another initial value.

Community
  • 1
  • 1
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • value-initialized is not standard for c++98, is it? – Slava Oct 14 '14 at 15:45
  • @Slava: Maybe not; I can't remember that far back. – Mike Seymour Oct 14 '14 at 15:46
  • I believe it is supported by gcc but it is a non standard extension for c++98 – Slava Oct 14 '14 at 15:48
  • @Slava: I don't see the relevance of historical trivia to this question. Value-initialisation has been standard for more than a decade; in any case, you should be using `vector` rather than juggling pointers. – Mike Seymour Oct 14 '14 at 15:55
  • Some people still have to work with C++98 and this will not compile there (unless there is extention on compiler), I think it would not hurt to mention that. – Slava Oct 14 '14 at 16:02