# 6.5 — Multidimensional Arrays

The elements of an array can be of any data type, including arrays! An array of arrays is called a multidimensional array.

Since we have 2 subscripts, this is a two-dimensional array.

In a two-dimensional array, it is convenient to think of the first (left) subscript as being the row, and the second (right) subscript as being the column. This is called row-major order. Conceptually, the above two-dimensional array is laid out as follows:

```[0][0]  [0][1]  [0][2]  [0][3]  [0][4] // row 0
[1][0]  [1][1]  [1][2]  [1][3]  [1][4] // row 1
[2][0]  [2][1]  [2][2]  [2][3]  [2][4] // row 2
```

To access the elements of a two-dimensional array, simply use two subscripts:

Initializing two-dimensional arrays

To initialize a two-dimensional array, it is easiest to use nested braces, with each set of numbers representing a row:

Although some compilers will let you omit the inner braces, we highly recommend you include them anyway, both for readability purposes and because of the way that C++ will replace missing initializers with 0.

Two-dimensional arrays with initializer lists can omit (only) the leftmost length specification:

The compiler can do the math to figure out what the array length is. However, the following is not allowed:

Just like normal arrays, multidimensional arrays can still be initialized to 0 as follows:

Note that this only works if you explicitly declare the length of the array! Otherwise, you will get a two-dimensional array with 1 row.

Accessing elements in a two-dimensional array

Accessing all of the elements of a two-dimensional array requires two loops: one for the row, and one for the column. Since two-dimensional arrays are typically accessed row by row, the row index is typically used as the outer loop.

In C++11, for-each loops can also be used with multidimensional arrays. We’ll cover for-each loops in detail later.

Multidimensional arrays larger than two dimensions

Multidimensional arrays may be larger than two dimensions. Here is a declaration of a three-dimensional array:

Three-dimensional arrays are hard to initialize in any kind of intuitive way using initializer lists, so it’s typically better to initialize the array to 0 and explicitly assign values using nested loops.

Accessing the element of a three-dimensional array is analogous to the two-dimensional case:

A two-dimensional array example

Let’s take a look at a practical example of a two-dimensional array:

This program calculates and prints a multiplication table for all values between 1 and 9 (inclusive). Note that when printing the table, the for loops start from 1 instead of 0. This is to omit printing the 0 column and 0 row, which would just be a bunch of 0s! Here is the output:

```1    2    3    4    5    6    7    8    9
2    4    6    8    10   12   14   16   18
3    6    9    12   15   18   21   24   27
4    8    12   16   20   24   28   32   36
5    10   15   20   25   30   35   40   45
6    12   18   24   30   36   42   48   54
7    14   21   28   35   42   49   56   63
8    16   24   32   40   48   56   64   72
9    18   27   36   45   54   63   72   81
```

Two dimensional arrays are commonly used in tile-based games, where each array element represents one tile. They’re also used in 3d computer graphics (as matrices) in order to rotate, scale, and reflect shapes.

### 96 comments to 6.5 — Multidimensional Arrays

• ASY

How to print size of multi dimensional array?
Because std::size(array) is not effective for multi dimensional array,
it will only return no of rows but not the column.

• This assumes that every sub-array has the same length. If they have different lengths, you'll need a loop.

• ASY

Thanks

• Hi I need your help
I did'nt get the last program can you explain it?

• Sky

Hi Sourabh,
1) for (int row = 0; row < numRows; ++row)
2)    for (int col = 0; col < numCols; ++col)
3)        product[row][col] = row * col;

first in the outer for loop(line no 1) we are taking row as a multiplier and in the inner for loop we are taking col as a number
so lets skip the zero multiplier(row = 0), start with row = 1
once row is initialize with value 1 inner for loop will start iteration.
col will be initialized with 0, 1, 2, 3,..., 9
and at line no 3 we are multiplying these value of col with that of row(i.e 1)
so in this way we are storing one's table
after that row =2 and then it will multiply col by row = 2
and give us the two's table. similarly it will continue till row = 9.
and then at printing the table we are excluding 0th row and 0th column because those will only contain zero.

• tbnal

how to initialise all elements of s fixed array from console

• Alex

If by console you mean user input, there's no easy way to do this. You're better off initializing to some initial value (e.g. 0) and then use a look to ask the user to provide values, and use assignment to get them into the fixed array.

• Haider

Hi,
Do multidimensional arrays allocate more memory than standard arrays?

• Hi Haider!

The standard doesn't force a specific implementation, so there is no general answer to your question.

Both arrays can store 10 ints.

Assuming x86_64 architecture with sizeof(int)=4 and sizeof(void*)=8; no compiler optimization; and ignoring the compiler-generated information block:

One way of implementing multidimensional arrays is:
@a takes up 8 bytes for the pointer to the first element and 4 bytes for each element. 8B + (10 * 4B) = 48B

@b takes up 8 bytes for the pointer to the first element, each sub-array takes up 8 bytes for the pointer to their first elements, and each int takes up 4 bytes. 8B + (5 * 8B) + (5 * 2 * 4B) = 88B

Conclusion: The more sub-arrays there are, the more memory is used.

GCC's way of implementing multidimensional arrays is:
A multidimensional array is a one-dimensional array. All elements are stored one after the other in memory, resulting the the same memory usage as one-dimensional arrays.

• Haider

Thanks for the explanation!

• hrmn

This means, initialize the first elements to 1 and 2, and the rest of the elements "as if they had static storage duration". There is a rule in C saying that all objects of static storage duration, that are not explicitly initialized by the programmer, must be set to zero.

i read this here https://stackoverflow.com/questions/15520880/initializing-entire-2d-array-with-one-value

can you please explain this , will it mean the array indices whose default value is set 0 as if static will have file scope? and what else automatically falls into static storage duration ? and does every data type is default 0 in this storage?
and why you didn't used {} instead of {0}?
sorry for so many questions..
Thanks

• Alex

Nope, because that's a C rule. C++ rules for initialization of arrays are here: https://en.cppreference.com/w/cpp/language/aggregate_initialization

In particular: "If the number of initializer clauses is less than the number of members and bases (since C++17) or initializer list is completely empty, the remaining members and bases (since C++17) are initialized by their default initializers, if provided in the class definition, and otherwise (since C++14) by empty lists, in accordance with the usual list-initialization rules (which performs value-initialization for non-class types and non-aggregate classes with default constructors, and aggregate initialization for aggregates)."

If you look up value initialization (https://en.cppreference.com/w/cpp/language/value_initialization), you'll see this: "...otherwise, the object is zero-initialized.", which is what happens here for the elements that don't have initializers specified.

• KKR

Can someone explain the output for the below program??

Output:
21
18
21

• KKR

• nascardriver

Hi KKR!

@Alex Do you have an explanation for why Line 8 in @KKR's code is a thing? I can't find any information about it. Probably because I don't know what to search for.

• KKR

Thank you nascardriver!!

And please post if you find info regarding that syntax. I find it quite weird!

• nascardriver

Found it!

a[b] is *(a + b)
and since *(a + b) == *(b + a)
a[b] == b[a]

Source: https://stackoverflow.com/questions/381542/with-arrays-why-is-it-the-case-that-a5-5a#381549

• KKR

Wow nice.. Thanks again!!

• Alex

Wow, I didn't know that was possible. How... weird. :)

• Will

Hello, why when I make a multidimensional array like this
std::array<std::array<int, 3>, 3> arr{ { { 1, 2, 3 },{ 4, 5, 6 },{ 7, 8, 9 } } }
I cant access it as in your example std::cout << array[0][1][2]
The last one says "Expression must have pointer to object"

• nascardriver

Hi Will!

Two issues,
1] Your array is two-dimensional (3x3), but you're trying to access it like a three-dimensional array. The deepest you can go on a two-dimensional array is arr[x][y], not arr[x][y][z].
2] You named your variable 'arr' but you're trying the access 'array'. That's what's causing your error.

• Will

Ahh I see lol I thought I was doing a 3d one
Yeah the name I noticed, was only curious about the last one asking for a pointer ^^
Thanks

• Micah

Maybe it's just for education purposes, but otherwise wouldn't you keep it simple and create a "int multiply(int x, int y){}" function and just make it so "array[row][col] = multiply(row, col)"  in a for loop?

• Alex

You could, but multiplying 2 integers is such a simple operation I'm not sure why you'd create a function for it.

• CuRSeD

how can I set the value of 2d array from the user?

int a, b;

cout << "Enter first value :  " ;
cin >> a ;
cout << "Enter second value : " ;
cin >> b ;
// i will get error

int myArray[a][b]

• Alex

You have to use dynamic allocation. I talk about this in a later lesson in this chapter.

• can we use vectors as multi-dimensional arrays?
if yes, how?

• Alex

You could have a vector of vectors. But you're maybe better off allocating a single dimensional vector and use math to map two coordinates down to one.