简体   繁体   中英

Pointer to a 2D array

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?

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 */

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 (eg ptr = (int *)p ), then ptr and p will have the same value (ie they will identify the same location in memory) but different type (ie 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] .

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 1 st element, a int* .

  • *ptr evaluates to an int .

    Passing an int to a function, results in passing an int to a function ... :-)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM