← All Lessons Lesson 13 / 68
Lesson 13

How a 3D Array Is Stored in Memory (Row-Major Order)

How a 3D Array Lives in Memory

A computer's memory is just one long line of numbered storage slots. But a three-dimensional array sounds like a box with rows, columns, and layers. So how does the computer fit a "box" into a single straight line? It uses a simple rule called row-major order. Let's walk through it with a real example and see exactly what happens when you read a value.

The example array

We have an integer array declared as array[2][2][3]. Think of it as 2 blocks, and each block is a small table of 2 rows and 3 columns. That gives 2 × 2 × 3 = 12 slots in total. The values stored are simply value1, value2, … up to value12.

In the source they label the sizes as D3 = 2, D2 = 2, and D1 = 3. Here D1 is the innermost (fastest-changing) dimension — the columns — and D3 is the outermost.

Flattening the box into a line

To place this box into straight-line memory, the computer writes the elements out one by one. The rule is: the lowest (innermost) dimension changes fastest. That means the last index counts up first, then the middle index, then the first index. The order of indices looks like this:

array[0][0][0]  -> value1
array[0][0][1]  -> value2
array[0][0][2]  -> value3
array[0][1][0]  -> value4
array[0][1][1]  -> value5
array[0][1][2]  -> value6
array[1][0][0]  -> value7
array[1][0][1]  -> value8
array[1][0][2]  -> value9
array[1][1][0]  -> value10
array[1][1][1]  -> value11
array[1][1][2]  -> value12

Notice how the rightmost number spins fastest (0, 1, 2), then resets, the middle number ticks up, and so on — exactly like an odometer in a car.

Where each value sits

Two facts decide the real memory positions:

  • Base address = 2 (the slot where the array starts).
  • Element size = 4 bytes, because each int takes 4 bytes.

So each value sits 4 bytes after the previous one: value1 at address 2, value2 at 6, value3 at 10, and so on, up to value12 at address 46.

Finding an element with a formula

When you write array[i][j][k], the computer does not search for the value. It calculates the address directly with a formula. The program already knows the dimensions, the base address, and the size of each element — that is all it needs. For array[i][j][k]:

address = base + size * ( D1 * ( D2 * i + j ) + k )

Let's plug in our two examples.

array[0][0][2]:

address = 2 + 4 * ( 3 * ( 2*0 + 0 ) + 2 )
        = 2 + 4 * ( 0 + 2 )
        = 2 + 8
        = 10

array[1][1][2]:

address = 2 + 4 * ( 3 * ( 2*1 + 1 ) + 2 )
        = 2 + 4 * ( 3*3 + 2 )
        = 2 + 4 * 11
        = 2 + 44
        = 46

So array[0][0][2] lives at address 10, and array[1][1][2] lives at address 46.

Reading the actual value (dereferencing)

Having an address is not the same as having a value. The final step is dereferencing: going to that address and reading the bytes there. Because the language knows the stored type is int (4 bytes), it grabs exactly 4 bytes starting at the address and reads them as one whole number.

  • At address 10 it finds value3.
  • At address 46 it finds value12.

This matches our flattened list above — the 3rd slot is value3, the 12th slot is value12.

Why this matters

All of this address math happens automatically, under the hood, in nearly every modern language. As a programmer you just write array[i][j][k] and get your value — you never do the arithmetic yourself. Low-level languages like C and C++ also give you pointers, which are variables that hold these memory addresses, so you can reach into that continuous block of memory directly. We used 4-byte integers here, but the exact same idea works for any data type — only the element size changes.

How a 3D Array Is Stored in Memory (Row-Major Order)
Diagram — click to zoom (scroll / drag to pan)