Reputation: 61
I have a 2D array (int s[4][2]
)and I created a pointer as int (*p)[2]
.
The pointer p
is now assigned the address of 1st element of row within a for loop.
for (int i = 0; i<4; i++)
p = &s[i];
Now when I try to write the array elements data using dereferencing, I get wrong values.
printf ("%d \n", *p)
However, if I create another pointer and link that with the previous pointer
int *ptr = p;
and dereference pointer ptr
I get correct values.
printf ("%d \n", *ptr)
When both the pointers are pointing to the same address why does one pointer (*ptr
) work as expected and other (*p
) does not return expected values?
Upvotes: 1
Views: 104
Reputation: 21955
By
int (*ptr)[2] ; // means int[2]<-(*ptr)
You got pointer to an array of two integers
The pointer p is now assigned the address of 1st element of row within a for loop.
This is not correct, technically p is assigned the address of the entire int[2]
block (Hint : use sizeof
to verify the size).
What is the problem with
printf ("%d \n", *ptr)
*ptr
by itself doesn't contain a integer but it holds the address of the first element of int[2]
ie *ptr
itself is a pointer.
A working example would be
int main(void)
{
int i;
int s[4][2]={{0,1},{2,3},{4,5},{6,7}};
int (*ptr)[2];
for(i=0;i<4;i++)
{
ptr=&s[i];
printf("i:%d\n",i);
printf("Element 1 : %d\n",(*ptr)[0]);
printf("Element 2 : %d\n",(*ptr)[1]);
/* Replacing (*ptr)[1] with *((*ptr)+1) gives you the same
* results
*/
}
return 0;
}
Output
i:0
Element 1 : 0
Element 2 : 1
i:1
Element 1 : 2
Element 2 : 3
i:2
Element 1 : 4
Element 2 : 5
i:3
Element 1 : 6
Element 2 : 7
Upvotes: 1
Reputation: 70883
When both the pointers are pointing to the same address why does one pointer (*ptr) work as expected and other (*p) does not return expected values?
*p
evaluates to an int[2]
, an array.
Passing an int[2]
, an array to a function, results in passing a pointer the array's 1st element, a int*
.
*ptr
evaluates to an int
.
Passing an int
to a function, results in passing an int
to a function ... :-)
Upvotes: 2
Reputation: 36597
p
is not a pointer to an int
. It is a pointer to an array of two int
. Therefore *p
is also an array of two int
. Since it is not an int
, printing it using %d
gives undefined behaviour.
You would not be able to "link" ptr
to p
because of a type mismatch (ptr
is a pointer to int
, and p
(as already noted) is a pointer to an array of two int
. Hence the assignment ptr = p
would not compile. If you are forcing it to compile (e.g. ptr = (int *)p
), then ptr
and p
will have the same value (i.e. they will identify the same location in memory) but different type (i.e. dereferencing them interprets the contents of that memory differently).
The value (ignoring type) of p
will be the address of s[0][0]
. Similarly, the value of ptr
will be the address of s[0][0]
.
As a result printf("%d\n", *ptr)
will print the value of s[0][0]
.
Upvotes: 2
Reputation: 121347
If p
is a pointer to array then *p
is array of 2 ints (int[2]
). So, you can't print an array element like this:
printf ("%d \n", *p);
To print the array elements through the pointer p
, you need to do:
printf ("%d \n", (*p)[0]); /* first element */
printf ("%d \n", (*p)[1]); /* second element */
Upvotes: 8