1

Look at the code given below:

#include<stdio.h>
int main()
{
     int (*p)[3];
     int a[3]={10,11,12};
     p=&a;
     printf("%d\n", *p[0]);
     printf("%d\n", *p[1]);
     printf("%d\n", *p[2]);
     return 0;
}

printf("%d\n", *p[0]); prints 10 which is expected.

But printf("%d\n", *p[1]); doesn't print 11.

And printf("%d\n", *p[2]); doesn't print 12.

Why? What's the reason behind this?

4
  • 1
    *p[k] is *(p[k]), not (*p)[k]. Commented May 22, 2018 at 8:58
  • are you aware that p is an array of three pointers of which one points to a[0] and the others to unkown memory? Commented May 22, 2018 at 9:02
  • Use a simple pointer (int *p;) and increment the pointer to show the other values of your array. Commented May 22, 2018 at 9:09
  • No. I thought p is an array of three pointers of which one points to a[0], one to a[1] and one to a[2]. I may have mistaken. But why the other pointers except p[0] point to unknown memory? @Kami Kaze Commented May 22, 2018 at 10:49

3 Answers 3

4

Operator precedence. [] has higher precedence than *, so when you write *p[0] it is the same as (*(*(p + 0))) - you do pointer arithmetic on an array pointer.

Meaning that for example p[1] gives you the address of p + 3*sizeof(int) bytes, which is accessing the array out of bounds.

Correct code should be:

 printf("%d\n", (*p)[0]);
 printf("%d\n", (*p)[1]);
 printf("%d\n", (*p)[2]);
Sign up to request clarification or add additional context in comments.

1 Comment

It's worth pointing out that C declarations were designed so that they mirror their usage. So if you needed to declare p as int (*p)[3] that's probably how you need to use it too. i.e. foo = (*p)[0]
2

*p[k] is *(p[k]), not (*p)[k].

That you get the expected result for *p[0] can be explained by its being the same as p[0][0], and it doesn't matter which order you put the zeros in.

p[1][0] (*p[1]), however, is not the same as p[0][1] ((*p)[1]).
(It's even undefined, since p[1] does not exist.)

Comments

0

int (*p)[3]; is an array of pointers to int.

int a[3]={10,11,12}; is an array of int. Arrays and pointers share a lot of properties. You can use array notation for pointers for example.

Lets take a normal pointer int *p = a which is the same as int *p = &a[0]. Now the pointer points to the first element of the array. And you can use it the same way as the array.

 printf("%d\n", p[0]); //10
 printf("%d\n", p[1]); //11
 printf("%d\n", p[2]); //12

What you did was getting the address of the array-"pointer" this yields the address of the first element of the array. Because &a == a

This gets written to the first element of your pointer array leaving you with

p[0] == a
p[1] == unknown
p[2] == unknown

by doing *p[0] you get the first element of p (p[0]) and dereference it *. This is the same as *a or a[0].

But by doing *p[1] you get to an unkown memory location(p[1]) and derefence it *. This is undefined behaviour.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.