1

I'm diving into C again after a number of years. I thought that the following two print statements would have evaluated to the same output, based on other answers I have found; however it does not appear to be the case.

int main()
{
    int** arr = malloc(
        3 * sizeof(int*)
    );
    for(int y = 0; y < 3; y++) {
        int* subarr = malloc(
            3 * sizeof(int)
        );
        for(int x = 0; x < 3; x++) {
            subarr[x] = y * 3 + x + 1;
        }
        arr[y] = subarr;
    }
    printf("%d\n", *(&arr[0][0]) + 3);
    printf("%d\n", (&arr[0][0])[3]);
}

Could anyone explain what is going on here/what I am missing?

ZombieTfk
  • 706
  • 7
  • 19
  • 1
    `x[3]` and `*(x+3)` are the same, but your first print does `(*x) + 3` which is different – M.M Apr 26 '20 at 23:48
  • 1
    also `(&arr[0][0])[3]` accesses out of bounds (causing undefined behaviour) – M.M Apr 26 '20 at 23:49
  • Ah okay, that explains why they evaluate to different values. Yeah I wasn't sure if it was legal or not to try and access the next sub-array by an out of bounds array access operator, so I guess that answers both of my questions, thank you. – ZombieTfk Apr 26 '20 at 23:57

1 Answers1

3

First of all, Let me explain what you are doing (At least for me).

arr[0] = A pointer to array {1, 2, 3}
arr[1] = A pointer to array {4, 5, 6}
arr[2] = A pointer to array {7, 8, 9}

First Case: *(&arr[0][0]) + 3

&arr[0][0] = Address of first element of {1, 2, 3}
*(&arr[0][0]) = 1      // Dereferencing the address 

So, It prints 1 + 3 = 4

Second Case: (&arr[0][0])[3]

(&arr[0][0]) = Address of first element of {1, 2, 3}

But the length of array is 3, So you can only access indices up to 2. So, It is causing undefined behaviour.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Appaji Chintimi
  • 613
  • 2
  • 7
  • 19