0

I stumbled upon a curious behaviour of std::array. Some containers such as std::vector initialise all cells, such that a vector of int will be a vector full of zeros by default. I tested whether this was also true for std::array. I discovered two things:

1) it looks like most cells are being initialised (but probably this has other reasons) and some are not.

2) the cells that are not being initialised are always the same. This holds true between separate executions of the program as well as between separate compilations. Consider the output below. for this code:

std::array<int, 100> a;
for (auto x : a) std::cout << x << " ";

I wonder now why these two things are this way. What causes this apparent initialisation (which probably is something else) and why are the non-initialised cells always the same ones (and sometimes eben have the same value as in the execution before)?

$ cocompile test.cpp
$ ./a.out
1583671832 1235456 1235456 1235456 1235456 1235456 0 0 0 0 
$ ./a.out
1539111448 1235456 1235456 1235456 1235456 1235456 0 0 0 0 
$ ./a.out
1509472792 1235456 1235456 1235456 1235456 1235456 0 0 0 0 
$ cocompile test.cpp
$ ./a.out
1551280664 32767 1551280664 32767 55136256 1 0 1 71644448 1 71644352 1 0 0 0 0 0 0 0 0 
$ ./a.out
1413601816 32767 1413601816 32767 192815104 1 0 1 407872800 1 407872704 1 0 0 0 0 0 0 0 0 
$ ./a.out
1542519320 32767 1542519320 32767 63897600 1 0 1 129918240 1 129918144 1 0 0 0 0 0 0 0 0 
$ cocompile test.cpp
$ ./a.out
1510054424 32767 1 0 1510054368 32767 145269321 1 1510054400 32767 1510054400 32767 1510054424 32767 96362496 1 0 1 145265952 1 145265856 1 0 0 0 0 0 0 0 0
$ ./a.out
1394678296 32767 1 0 1394678240 32767 378704457 1 1394678272 32767 1394678272 32767 1394678296 32767 211738624 1 0 1 378701088 1 378700992 1 0 0 0 0 0 0 0 0 
$ ./a.out
1436727832 32767 1 0 1436727776 32767 353342025 1 1436727808 32767 1436727808 32767 1436727832 32767 169689088 1 0 1 353338656 1 353338560 1 0 0 0 0 0 0 0 0 
lo tolmencre
  • 3,804
  • 3
  • 30
  • 60
  • Possible duplicate of [Default initialization of std::array?](https://stackoverflow.com/questions/18295302/default-initialization-of-stdarray) –  Jul 14 '17 at 02:15
  • no, that is not my question. – lo tolmencre Jul 14 '17 at 02:20
  • I upvoted the question, because I don't think the downvote was justified. OTOH, you should accept @duong_dajgja's answer, because that's the correct one: those array values are _not_ actually "initialized" in the common sense: they are only guaranteed to be valid for their type (int), but they are still unknown. (Any regularity is just an accidental peculiarity of the runtime environment.) – Sz. Aug 03 '19 at 23:35

2 Answers2

1

Constructor of std::array initializes the array following the rules of aggregate initialization (note that default initialization may result in indeterminate values for non-class T).

Please check the constructor at std::array

Since int is a non-class the values of elements in your a array are indeterminate then they can be just garbage things that have resided at the location allocated to elements of your a. That's why you see different results from time to time.

In short, this is an undefined behavior since you are accessing un-initialized variables.

duong_dajgja
  • 4,196
  • 1
  • 38
  • 65
0

Looks like undefined behavior. If you want to default initialize std::array, do this instead:

std::array<int, 100> a = {};
yizzlez
  • 8,757
  • 4
  • 29
  • 44
  • But the pattern is pretty regular for undefinedness. I guess the answer to the question lies in hardware and drivers then? – lo tolmencre Jul 14 '17 at 02:20
  • 4
    @lotolmencre Undefined behavior includes appearing to have a pattern. There isn't much point in trying to reason about the contents of uninitialized memory. – Blastfurnace Jul 14 '17 at 02:30
  • It is _defined behavior_ actually: the definition says, however, that the _values_ themselves can, indeed, be undefined. (See @duong_dajgja's answer.) – Sz. Aug 03 '19 at 23:40