DEV Community

Cover image for Understanding Memory Addressing for Multi-Dimensional Arrays in Python and C
Laiba Asim✨
Laiba Asim✨

Posted on • Edited on

Understanding Memory Addressing for Multi-Dimensional Arrays in Python and C

In computers, memory is organized linearly, like a long row of boxes. Each box has a unique address called a memory address, and each address can store a value. When we work with multi-dimensional data like a 2D or 3D array, we need a way to map its rows and columns (or layers) into this linear memory.


Key Ideas

1. Linear Memory Addressing

  • Memory cells are numbered one after another.
  • For example, if the first memory cell has an address of 10000, the next would be 10001, and so on.

2. Multi-dimensional Arrays in Linear Memory

Multi-dimensional arrays (like a 2D table) are stored in this linear memory row by row:

  • Row-by-row storage: First store all elements of the first row, then the second row, and so on.

For example, a 3x4 (3 rows, 4 columns) array looks like this in memory:

0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
  • Linear Indexing:

    • The array above is stored linearly as:
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    
  • To find the linear index of any element, use:

    Linear Index=Row Index × Number of Columns + Column Index
    

Example:

  • For the element at row 1, column 2 (array[1, 2]), the linear index is:

    Linear Index =1 × 4 + 2 = 6
    
  • So, array[1, 2] corresponds to the 6th element in linear memory.


3. Reverse: From Linear to Multi-dimensional Index

When you have a linear index and want the original row and column:

  • Use the function np.unravel_index.
  • It takes the linear index and the shape of the array as input and returns the row and column.

Example:

np.unravel_index(6, (3, 4))
Enter fullscreen mode Exit fullscreen mode

Output:

(1, 2)
Enter fullscreen mode Exit fullscreen mode

4. Why Does This Matter?

  • Computers store data as a single linear row, but we often think of data as multi-dimensional arrays.
  • Functions like np.unravel_index and the formula for linear indexing help us efficiently translate between these two views.

Additional Notes

  1. Memory Size:

    • The memory address of an item depends on its size in bytes (e.g., integers take 4 or 8 bytes). For example:
      • For a 4-byte integer, the memory address of the 5th element would be:
    Base Address + 4 × (Index)
    
  2. Column-major vs. Row-major Order:

    • NumPy typically uses row-major order (row by row), but it can also work in column-major order (column by column), depending on settings.

This flexibility allows NumPy to adapt to different ways data might be stored in memory.

"Crafted with love by Laiba Asim"
Github | Linkedin

Top comments (0)