Address Calculation
0%
2D Arrays  ·  IIT Level

Address Calculation in
2D Arrays

Row-Major Order and Column-Major Order — formulas, memory maps, 8 fully worked examples with new numbers, and practice problems.

§1

Why We Need Address Calculation

A 2D array looks like a grid on paper, but computer memory is one-dimensional — a long line of bytes. To access arr[i][j], the compiler must calculate exactly which byte in that line holds the value. This calculation depends on whether the array is stored in Row-Major Order or Column-Major Order.

  • C uses Row-Major Order — all of row 0 is stored first, then row 1, then row 2
  • Fortran uses Column-Major Order — all of column 0 first, then column 1...
  • Knowing this determines which loops are faster and how to compute addresses

To access an element of a two-dimensional array, you must specify the index number of both the row and column. For example, matrix[0][2] accesses the value in the first row (0) and third column (2).

access_demo.c
C
/* Accessing a 2D array element */
int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} };

printf("%d", matrix[0][2]);  /* Outputs 2 — row 0, col 2 */
printf("%d", matrix[1][1]);  /* Outputs 6 — row 1, col 1 */
row-major order
§2

Row-Major Order — C Default

In Row-Major Order, the array arr[x][y] is stored row by row in memory. When you move from one element to the next, you go across the current row before jumping to the next row.

Row-Major Address Formula
Address of arr[i][j]  =  Base Address  +  (i × y + j) × size

where:
  i    = row index
  j    = column index
  y    = total number of COLUMNS in the array
  size = bytes per element (int=4, float=4, char=1, double=8)

int arr[3][4] stored in memory — row by row (each int = 4 bytes)

+0
[0][0]
10
[0][1]
12
[0][2]
14
[0][3]
16
[1][0]
20
[1][1]
22
[1][2]
24
[1][3]
26
[2][0]
30
[2][1]
32
[2][2]
34
[2][3]
36
Blue=row0 · Green=row1 · Purple=row2 · Gold=[1][3] highlighted for example below
Example R1 — Find address of arr[3][4] in array arr[6][8], base=200, int=4 bytes
Given: arr[6][8] · Base=200 · size=4 · Find: arr[3][4] → i=3, j=4, y(cols)=8
Step 1 — Apply formula
Address = Base + (i × y + j) × size
Step 2 — Substitute values
= 200 + (3 × 8 + 4) × 4
Step 3 — Calculate bracket
= 200 + (24 + 4) × 4 = 200 + 28 × 4 = 200 + 112
Address of arr[3][4] = 312
Example R2 — Find address of arr[5][3] in array arr[7][6], base=500, int=4 bytes
Given: arr[7][6] · Base=500 · size=4 · Find: arr[5][3] → i=5, j=3, y(cols)=6
Step 1 — Apply formula
Address = Base + (i × y + j) × size
Step 2 — Substitute
= 500 + (5 × 6 + 3) × 4
Step 3 — Calculate
= 500 + (30 + 3) × 4 = 500 + 33 × 4 = 500 + 132
Address of arr[5][3] = 632
Example R3 — Find address of arr[2][7] in array arr[4][10], base=1000, int=4 bytes
Given: arr[4][10] · Base=1000 · size=4 · Find: arr[2][7] → i=2, j=7, y(cols)=10
Step 1 — Apply formula
Address = Base + (i × y + j) × size
Step 2 — Substitute
= 1000 + (2 × 10 + 7) × 4
Step 3 — Calculate
= 1000 + (20 + 7) × 4 = 1000 + 27 × 4 = 1000 + 108
Address of arr[2][7] = 1108
Example R4 — Find address of arr[4][5] in array arr[5][8], base=2000, double=8 bytes
Given: arr[5][8] · Base=2000 · size=8 (double) · Find: arr[4][5] → i=4, j=5, y=8
Step 1 — Apply formula
Address = Base + (i × y + j) × size
Step 2 — Substitute
= 2000 + (4 × 8 + 5) × 8
Step 3 — Calculate
= 2000 + (32 + 5) × 8 = 2000 + 37 × 8 = 2000 + 296
Address of arr[4][5] = 2296
column-major order
§3

Column-Major Order

In Column-Major Order, the array is stored column by column. All elements of column 0 are stored first, then column 1, etc. The formula changes — now you multiply j by the number of rows (not columns).

Column-Major Address Formula
Address of arr[i][j]  =  Base Address  +  (j × x + i) × size

where:
  i    = row index
  j    = column index
  x    = total number of ROWS in the array
  size = bytes per element
Key difference from row-major:
Row-major: multiply i by COLUMNS → (i × COLS + j) × size
Column-major: multiply j by ROWS → (j × ROWS + i) × size
In C, always use row-major. Column-major appears only in exam questions asking you to compare.
Example C1 — Find address of arr[3][4] in array arr[6][8], base=200, int=4 bytes (Column-Major)
Given: arr[6][8] · Base=200 · size=4 · Find: arr[3][4] → i=3, j=4, x(rows)=6
Step 1 — Column-major formula
Address = Base + (j × x + i) × size
Step 2 — Substitute
= 200 + (4 × 6 + 3) × 4
Step 3 — Calculate
= 200 + (24 + 3) × 4 = 200 + 27 × 4 = 200 + 108
Address of arr[3][4] = 308 (Row-major gave 312 — different!)
Example C2 — Find address of arr[5][3] in array arr[7][6], base=500, int=4 bytes (Column-Major)
Given: arr[7][6] · Base=500 · size=4 · Find: arr[5][3] → i=5, j=3, x(rows)=7
= 500 + (3 × 7 + 5) × 4 = 500 + (21+5) × 4 = 500 + 26 × 4 = 500 + 104
Address of arr[5][3] = 604 (Row-major gave 632)
Example C3 — Find address of arr[2][7] in array arr[4][10], base=1000, int=4 bytes (Column-Major)
Given: arr[4][10] · Base=1000 · size=4 · Find: arr[2][7] → i=2, j=7, x(rows)=4
= 1000 + (7 × 4 + 2) × 4 = 1000 + (28+2) × 4 = 1000 + 30 × 4 = 1000 + 120
Address of arr[2][7] = 1120 (Row-major gave 1108)
Example C4 — Find address of arr[4][5] in array arr[5][8], base=2000, double=8 bytes (Column-Major)
Given: arr[5][8] · Base=2000 · size=8 · Find: arr[4][5] → i=4, j=5, x(rows)=5
= 2000 + (5 × 5 + 4) × 8 = 2000 + (25+4) × 8 = 2000 + 29 × 8 = 2000 + 232
Address of arr[4][5] = 2232 (Row-major gave 2296)
Quick comparison table — same element, same array, different storage order gives different addresses:
ArrayElementBaseSizeRow-MajorCol-Major
arr[6][8]arr[3][4]2004312308
arr[7][6]arr[5][3]5004632604
arr[4][10]arr[2][7]1000411081120
arr[5][8]arr[4][5]2000822962232
c program proof
§4

C Program — Verify Address Calculations

verify_addresses.c
C
#include <stdio.h>

int main() {
    int arr[4][10];
    long base, offset;
    int  i, j;

    base = (long)&arr[0][0];

    printf("Base address (arr[0][0]) = %ld\n\n", base);
    printf("%-12s %-14s %-12s\n",
           "Element", "Actual Addr", "Offset");
    printf("--------------------------------------\n");

    /* Print first 3 rows */
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 4; j++) {
            offset = (long)&arr[i][j] - base;
            printf("arr[%d][%d]   %ld    +%ld\n",
                   i, j, (long)&arr[i][j], offset);
        }
    }

    /* Verify formula for arr[2][7] */
    printf("\n--- Verify Example R3 ---\n");
    printf("Formula:  base + (2*10+7)*4 = base + %d\n", ((2*10)+7)*4);
    printf("Actual:   arr[2][7] offset = +%ld\n",
           (long)&arr[2][7] - base);
    printf("Match:    %s\n",
           ((2*10+7)*4 == (long)&arr[2][7]-base) ? "YES" : "NO");
    return 0;
}
terminal — shows row-major pattern in real memory
output
Base address (arr[0][0]) = 1000  (example)

Element      Actual Addr    Offset
--------------------------------------
arr[0][0]    1000           +0
arr[0][1]    1004           +4
arr[0][2]    1008           +8
arr[0][3]    1012           +12
arr[1][0]    1016           +16   ← row 1 starts at +40 (4 cols × 4 bytes)
arr[1][1]    1020           +20
arr[2][0]    1040           +40   ← row 2 starts at +80
arr[2][7]    1108           +108

--- Verify Example R3 ---
Formula:  base + (2*10+7)*4 = base + 108
Actual:   arr[2][7] offset = +108
Match:    YES
quiz
Q

Address Calculation Quiz

Question 1 of 4

In Row-Major order, find address of arr[2][3] in array arr[5][5]. Base=300, int=4 bytes.

Question 2 of 4

In Column-Major order, find address of arr[2][3] in array arr[5][5]. Base=300, int=4 bytes.

Question 3 of 4

For double arr[6][8], base=4000. What is the address of arr[3][5] in row-major? (double=8 bytes)

Question 4 of 4

C uses Row-Major order. Which loop order is FASTER for processing a 2D array row by row?

Checklist

  • I know C stores 2D arrays in Row-Major order (row by row)
  • Row-Major formula: Base + (i × COLS + j) × size
  • Column-Major formula: Base + (j × ROWS + i) × size
  • I can identify i=row, j=col, y=total cols, x=total rows, size=bytes per type
  • I completed all 8 worked examples and got the same answers
  • I completed the quiz