I'm relatively new to C programming and I stumbled upon a for me unexplainable behaviour while running the following code and debugging it using gdb and lldb.
In short: When swapping the indices i and j (max i != max j) when accessing a value in a two-dimensional Array inside a double nested for-loop it does not seem to matter if I access the value using array[i][j] or array[j][i].
The two loops and arrays are mostly identical.
unsigned matrix[3][1] =
{
{3},
{4},
{5}
};
//Loop1
for (size_t i = 0; i < sizeof(matrix) / sizeof(*matrix); i++)
{
for (size_t j = 0; j < sizeof(matrix[i]) / sizeof(*matrix[i]); j++)
{
matrix[i][j] <<= 1;
printf("matrix[%zu][%zu] has the value: %d\n", i, j, matrix[i][j]);
}
}
//same two dimensional array as matrix
unsigned matrix2[3][1] =
{
{3},
{4},
{5}
};
//Loop2, basically the same loop as Loop1
for (size_t i = 0; i < sizeof(matrix2) / sizeof(*matrix2); i++)
{
for (size_t j = 0; j < sizeof(matrix2[i]) / sizeof(*matrix2[i]); j++)
{
//swapped i and j here
matrix2[j][i] <<= 1;
printf("matrix2[%zu][%zu] has the value: %d\n", j, i, matrix2[j][i]);
}
}
Am I missing here something?
In both cases i is passed the value 2 at the end of the outer loop and j the value 0 at the end of the inner loop.
Intuitively, matrix[0][2] should throw an exception as each row only has one element.
I will take a slightly different approach than the other respondents.
You are technically not reading outside of the array's boundary as far as the memory layout is concerned. Looking at it from a human perspective you are (the index [0][2] doesn't exist!), but the memory layout of the array is contiguous. Each of the "rows" of the matrix are stored next to each other.
In memory, your array is stored as: | ? | 3 | 4 | 5 | ? |
So when you index to matrix[1][0]
or matrix [0][1]
you are accessing the same position in memory. This would not be the case if your array was larger than 1 dimension wide.
For example, replace your array with the following one and experiment. You can access integer '4' either by indexing matrix[0][2]
, or matrix [1][0]
. The position [0][2] shouldn't exist, but it does because the memory is contiguous.
unsigned matrix[3][2] =
{
{3, 6},
{4, 8},
{5, 10}
};