user4437794
user4437794

Reputation:

The outputs of my program are confusing

I have code something like this

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); 
 }

The output for all of the 3 values are same can anyone tell me why.?

Upvotes: 1

Views: 78

Answers (3)

sps
sps

Reputation: 2730

First of all - as others have pointed out - you need to use the correct format specifiers, and cast to these values to pointers.


Now as to why all of them give same value.

Here x is an array. And the type of its elements are unsigned int[3]. i.e. x is an array of unsigned int[3] arrays.

First, x + 3 gives the address of fourth element in your array. That is the address of {10, 11, 12}. The address of this array in memory will be the address of its first element in memory. That is the address of 10 in memory. Note that this value is int (*) [3], i.e. address of an unsigned int[3] array.

Second, * (x + 3) is equivalent to x[3], which is the fourth element, which is unsigned int[3]. It is the array {10, 11, 12}. This value is pointing to the first element of array {10, 11, 12}. That is, this value is pointing to 10. Note that this value is unsigned int[3].

Third *(x+2) + 3 : Here *(x + 2) is equivalent to x[2] which is an unsigned int[3], which is {7, 8, 9} array , and when you do a + 3 you are again getting the address of 10. Note that this value is unsigned int[3].

So, you see in all three cases your result is the same address in memory, i.e. the address where 10 is stored - even though you are representing different things at different time; unsigned int (*)[3] at first, and unsigned int[3] at second and third.

Upvotes: 1

You get wrong values because you do the pointer arithmetic wrong.
x is of type unsigned int[4][3], an array of length 4, each member of which is itself an array of length 3.

So what is x+3? It's the address of the last member in x (remember that the members of x are arrays).
And therefore *(x+3) is itself an array. But what happens to arrays when you pass them as function parameters? They decay into pointers. So you see the address of the first element in that array, mangled by the wrong type specifier in printf.

Okay, let's get to element x[2][3] for instance. It will be an expression of this sort *(*(x+2)+3) which is all in all equivalent to *(&x[0][0] + 2*3 + 3).

Upvotes: 0

Sergio
Sergio

Reputation: 8209

Distilled undefined behavior:

printf("%u, %u, %u", x + 3, * (x + 3), * (x + 2) + 3);

All extra arguments must be unsigned int, but the 2d is unsigned int (*)[3], the 3d is unsigned int *, the 4th is unsigned int * too.

Upvotes: 0

Related Questions