Card 02/ 09

WalkthroughDifficulty: Beginner4 min

Compute an Element's Address in One and Two Dimensions

Base address plus index times cell size, and for a grid, row times width first.

Every element of an array lives at an address computed from its index, and a grid stored in one array adds one step to that computation. This card covers the one-dimensional formula, the row-major layout that stores a grid row by row, and the two-dimensional formula that follows from it.

The goal is to find the element at a given row and column of a grid kept in one flat array. You need multiplication, and the fact that an array's cells are the same size and sit side by side.

From a grid cell to an index, and from an index to an address

Multiply the index by the cell size

In one dimension, cell i starts at base + i × size, where base is the address of cell 0 and size is the number of bytes in a cell. For prices stored as eight-byte numbers from address 5000:

Addresses of prices[i], eight bytes a cell from 5000, printed by a run
IndexArithmeticAddress
05000 + 0 × 85000
15000 + 1 × 85008
25000 + 2 × 85016
95000 + 9 × 85072

Lay the grid out row by row

Memory has one dimension, so a grid of three rows and four columns has to be put in some order. Row-major order stores row 0 first, then row 1, then row 2, so each row fills cols consecutive cells. Python's lists of lists and Java's int[][] keep each row as an array of its own instead; a flat array is what you build when the whole grid should sit in one block, as an image's pixels usually do.

The 3 by 4 grid, each letter with its index in the flat array
RowColumn 0Column 1Column 2Column 3
Row 0A (0)B (1)C (2)D (3)
Row 1E (4)F (5)G (6)H (7)
Row 2I (8)J (9)K (10)L (11)

Skip whole rows, then count along

To reach row r, skip r full rows of cols cells each, then move c cells along: index = r × cols + c. The multiplier is the number of columns, because a row is as long as the grid is wide.

Applied to the grid above, the formula picks each letter out of the flat array.

Before the trace: at which index of the flat array does grid[1][2], the letter G, sit?

At 6: skip one row of four cells, then move two along.

The trace reads three cells through the flat array; index marks r × cols + c.

Reading the grid through its flattened row

Inputa grid of three rows and four columns, stored row by row as A to L

  1. Read grid[0][0]

    1. Aindex
    2. B
    3. C
    4. D
    5. E
    6. F
    7. G
    8. H
    9. I
    10. J
    11. K
    12. L

    0 × 4 + 0 = 0: A, the first cell of row 0.

  2. Read grid[1][2]

    1. A
    2. B
    3. C
    4. D
    5. E
    6. F
    7. Gindex
    8. H
    9. I
    10. J
    11. K
    12. L

    1 × 4 + 2 = 6: skip the four cells of row 0, then two more, to G.

  3. Read grid[2][3]

    1. A
    2. B
    3. C
    4. D
    5. E
    6. F
    7. G
    8. H
    9. I
    10. J
    11. K
    12. Lindex

    2 × 4 + 3 = 11: skip two rows of four, then three more, to L.

ResultCell (r, c) sits at index r × cols + c, here r × 4 + c.

The address then follows from the first step: base + (r × cols + c) × size. With four-byte cells from address 1000, G sits at 1000 + 6 × 4 = 1024.

To know the formula is right, a check compares each cell of the grid with the one the formula picks out of the flat array.

grid_address.pypy
rows = 3
cols = 4
grid: list[list[str]] = [
    ["A", "B", "C", "D"],
    ["E", "F", "G", "H"],
    ["I", "J", "K", "L"],
]
flat: list[str] = [cell for row in grid for cell in row]


def flat_index(r: int, c: int) -> int:
    return r * cols + c


mismatches = 0
for r in range(rows):
    for c in range(cols):
        if flat[flat_index(r, c)] != grid[r][c]:
            mismatches += 1
print(" ".join(flat))
print(f"{rows * cols} cells checked, {mismatches} mismatches")
print(f"grid[1][2] = {grid[1][2]}, flat[{flat_index(1, 2)}] = {flat[flat_index(1, 2)]}")
OutputRan with python:3.14.8-slim-trixie (Python 3.14.8)
A B C D E F G H I J K L
12 cells checked, 0 mismatches
grid[1][2] = G, flat[6] = G

The formula is right when it agrees with the layout for every cell, not only the one you tried, and the check found no mismatch in 12. A wrong multiplier usually fails at the first cell of row 1: r × rows + c sends grid[1][0] to index 3, which holds D rather than E.