cpointersundefined-behaviorunsigned-integer

Unknown Output of C code


How does the following code give the answer as 2036, 2036, 2036.

What is the output of the following C code? Assume that the address of x is 2000 (in decimal) and an integer requires four bytes of memory.

int main()
{ 
   unsigned int x[4][3] = {{1, 2, 3}, {4, 5, 6}, 
                           {7, 8, 9}, {10, 11, 12}};
   printf("%u, %u, %u", x+3, *(x+3), *(x+2)+3);
}

Solution

  • As you've just found out, people can be a bit harsh on SO if you don't post carefully crafted code. To print addresses, use either %p or macros from <inttypes.h> such as PRIXPTR and casts to uintptr_t.

    Using just %p, your code should probably read:

    #include <stdio.h>
    
    int main(void)
    { 
        unsigned int x[4][3] =
        {
            {  1,  2,  3 }, {  4,  5,  6 }, 
            {  7,  8,  9 }, { 10, 11, 12 }
        };
        printf("%p\n", (void *)x);
        printf("%p, %p, %p\n", (void *)(x+3), (void *)(*(x+3)), (void *)(*(x+2)+3));
        return 0;
    }
    

    Now you have defined behaviour, though the values won't be convenient like 2000 and 2036.

    However, x+3 is the address of the fourth array of 3 int after the start of the array, so assuming sizeof(int) == 4 as stated, that is 36 bytes after the start of x — 2036 if x is at 2000.

    *(x+3) is the address of the start of the fourth array; that is at 2036 under the same assumptions.

    *(x+2)+3 adds 3 to the address of the third array of 3 int and then adds 3 more to it. That too ends up 36 bytes after the start of x, or at 2036 if x is at 2000.

    On my 64-bit machine, the output reads:

    0x7fff5800a440
    0x7fff5800a464, 0x7fff5800a464, 0x7fff5800a464
    

    Hex 0x24 is 36 decimal, of course.