data-structures · intermediate · ~15 min
Manual row-major addressing and the equivalence with linear iteration.
Implement void flatten_row_major(const int *src, int rows, int cols, int *dst) that copies a rows x cols grid (given as a contiguous block in src, row by row) into the 1D buffer dst in row-major order.
This is essentially a buffer copy, but the exercise is to write the explicit double loop and convince yourself that row-major [i * cols + j] indexing matches.
src = [1,2,3, 4,5,6] (2x3 grid)
flatten_row_major(src, 2, 3, dst)
dst -> [1, 2, 3, 4, 5, 6]
rows == 0 or cols == 0 — no work to do.Functions like cv::Mat::reshape, numpy.ravel(), and BLAS cblas_dgemm all expect contiguous row-major layouts.
Real C code rarely uses int ** for matrices because pointer indirection trashes the cache. Storing a 2D grid in a single contiguous block and indexing [i * cols + j] is the standard high-performance layout (used by NumPy, BLAS, image libraries, etc.).
src of size rows*cols, then rows, cols, then dst of the same size.
dst filled with the same values in the same order.
Use the explicit i * cols + j indexing form (don't just memcpy).
void flatten_row_major(const int *src, int rows, int cols, int *dst) { /* TODO */ }
Mixing up i and j (column-major addressing). Off-by-one on the outer loop. Mismatched destination size.
0 rows; 0 cols; 1x1; non-square (rows != cols).
O(rows * cols).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.