cparameter-passing

Passing arguments to the function


The output of the following code segment is 9. I think the argument, a, of the function foo is passed by value. Is my assumption correct? If so, how does the output become 9?

#include <stdio.h>

void foo(int[][3]);

int main(void)
{
   int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

   foo(a);
   printf("%d\n", a[2][1]);

   return 0;
}

void foo(int b[][3])
{
   ++b;
   b[1][1] = 9;
}

Solution

  • The [] syntax for a function parameter's type is just syntactic sugar. A pointer is passed in this case, just like with any other use of an array in a function call context. That means your foo() function's signature is equivalent to:

    void foo(int (*b)[3])
    

    That is, it accepts a pointer to an array of three integers. With that in mind, let's look at what your implementation does. First, ++b advances the pointer to point to the next array of 3 integers in memory. That is, it advances b by 3 * sizeof(int). In the case of your program, that means it's pointing at the "middle row" of a - the { 4, 5, 6 } row.

    Next, you access element [2][1] of the new b. That is, row two, element one of this new offset logical array. That causes your program to write to an address past the end of a, which is undefined behaviour. At this stage, all bets are off. The output of your program could be anything.

    You can get back to defined behaviour by changing that line to:

    b[1][2] = 157;
    

    for example. Then, print a[2][2] to see the change from the context of your main() function.