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 
3
  • Possible duplicate of Default initialization of std::array? Commented Jul 14, 2017 at 2:15
  • no, that is not my question. Commented Jul 14, 2017 at 2: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.) Commented Aug 3, 2019 at 23:35

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

std::array<int, 100> a = {}; 

3 Comments

But the pattern is pretty regular for undefinedness. I guess the answer to the question lies in hardware and drivers then?
@lotolmencre Undefined behavior includes appearing to have a pattern. There isn't much point in trying to reason about the contents of uninitialized memory.
It is defined behavior actually: the definition says, however, that the values themselves can, indeed, be undefined. (See @duong_dajgja's answer.)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.