1

I thought I was OK at C style arrays, apparently not. I can't figure this out.

Say I declare a function

void RotateMatrix(int ** matrix, int n)
{
    auto x = matrix[0][0];
}

(assume matrix is square). Driving it from the main function

void main() 
    {
    int matrix[4][4] = 

    { 
        {1, 2, 3, 4}, 
        {5, 6, 7, 8}, 
        {9, 10, 11, 12}, 
        {13, 14, 15, 16} 
    };

    RotateMatrix((int**) matrix, 4);
}

Basically, matrix[0][1] results in a buffer overflow. Debugging it, matrix[0][0] tries to go to the address 0x0000000200000001, a combination of the first 8 bytes in the array, presumably as int is 4 bytes and int* is 8 bytes, and int** is a pointer to a pointer of ints, hence it treats the first 2 matrix entries as int*. However, this confused me as answers like bobobobo's on How to pass a multidimensional array to a function in C and C++ seems to show you can use the int** approach. I'm confused. I've seen other SO posts say the same thing, so why does it work for them?

I thought matrix[0][0] it would do matrix[0]'s address plus offset 0 * sizeof(int) (which would still be the first element)

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 4
    Don't use casts. Whenever you cast, you've misunderstood the type system. – Kerrek SB Jan 28 '18 at 01:27
  • spidy sense are telling me it might be because of dynamic array allocation where you do actually allocate an array of int* and then for each row an array of ints. Correct? – DoubtingThomas Jan 28 '18 at 01:28
  • Read [AnT's answer](https://stackoverflow.com/a/2828693/1480131) in the same thread you've linked in your question. `matrix` does not decay in a `int**` but in a `int (*)[4]`. – Pablo Jan 28 '18 at 01:35
  • If you removed the cast, the compiler clearly shows you the error. When you applied the cast, you told the compiler to "shut up, leave me alone, I know what I'm doing". The compiler knew better, tried to let you know, but you didn't listen and went ahead with the cast. – PaulMcKenzie Jan 28 '18 at 03:11

1 Answers1

2

An array of array decays not into a pointer to pointer, but into a pointer to array. So the array int matrix[4][4] decays not into int **, but into int (*)[4].

That is why you need to get rid of the cast and change the signature of RotateMatrix.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75