+0+4+8+12+16int a[4] · offsets in bytesstd::array<int, 4> bb[0]b[1]b[2]b[3]b.at(4)$ ./arrays144a[0]a[1]a[2]a[3]a[4]?int sum1#include <array>2#include <iostream>3int main() {4 int a[4] = {3, 1, 4, 1};5 a[2] = 9;6 int sum = 0;7 for (int x : a) sum += x;8 std::array<int, 4> b = {3, 1, 4, 1};9 std::cout << sum << '\n';10 std::cout << b.size() << '\n';11}314193141i?!144
Violet card: the code (arrays.cpp)Slate cells: the array's elements in memory; khaki: sum; red dashed: past the endTokens: values moving between code and memory, and the index cursor iIn front: the code card arrays.cpp. On the right: the array a as four memory cells side by side at byte offsets +0, +4, +8 and +12, a dashed cell just past its end, the int sum behind it, the std::array b in front and the output screen at the back. The numbers on line 4 lift into a's cells, a[2] = 9 replaces one value, and the loop carries every element into sum until it reads 14. An index cursor shows that a[i] is found by arithmetic, and that a[4] is past the end with no check. b holds the same four ints; the program prints 14 and 4, and b.at(4) checks the index and refuses.

The built-in array

  1. int a[4] = {3, 1, 4, 1}; makes an array: four ints of one type, stored side by side in one block of memory. The 4 is its size. It is fixed when you compile, so the array can never grow or shrink.

Using it

std::array

What happens

;; step 1/9 · declare
4  int a[4] = {3, 1, 4, 1};
   int     the type of every element
   a       the array's name
   [4]     the size: 4 elements, fixed at compile time
   {...}   the starting values, in order
memory  one block, no gaps:  3 | 1 | 4 | 1

sizeof(int) is 4 bytes on every mainstream platform (the ILP32, LP64 and LLP64 data models used by Linux, macOS and Windows). The C++ standard only promises at least 16 bits, so check with sizeof if it matters. The figure marks byte offsets from the start of the array (+0, +4, +8, +12) rather than real addresses: the real address of a changes from run to run.