简体   繁体   中英

Array Pointer not returned the expected value

Per a different thread I learned that using '&' with an array doesn't return a double pointer but rather a pointer array.

int x[9] = {11, 22,33,44,55,66,77,88,99};
int (*xpt)[9] = &x;    <---This is the focus of this thread.

The following code compiles and executes.

#include <stdio.h>
int main () 
{
    int x[9] = {11, 22,33,44,55,66,77,88,99};
    int (*xpt)[9] = &x;

    printf("xpt[0] = %d\n", xpt[0]);
    printf("xpt[0][0] = %d\n", xpt[0][0]);
    printf("xpt[0][1] = %d\n", xpt[0][1]);
    printf("*xpt[0] = %d\n", *xpt[0]);
    printf("*xpt[1] = %d\n", *xpt[1]);

   return 0;
}

Here is the output.

> ./runThis
xpt[0] = 155709776
xpt[0][0] = 11
xpt[0][1] = 22
*xpt[0] = 11
*xpt[1] = 32766

The questions pertain to the output. Since xpt is an array pointers (I assume) xpt[0] is simply displaying the address of the first value 11.

I was a bit surprised that the following 2 lines worked.

  xpt[0][0] = 11
  xpt[0][1] = 22

After thinking about it, it almost makes sense as I was thinking xpt[0] and *xpt could be used interchangeably until the following two lines disproved that :

  *xpt[0] = 11
  *xpt[1] = 32766

Why does *xpt[0] return the expected value but not *xpt[1] ?

It should be (*xpt)[0] to get the array elements. Otherwise you are having undefined behavior here. Because you are accessing some memory that will be out of the bound or that you shouldn't/ or you don't have permission to.

Also don't be suprised by xpt[0][0] that is equivalently what I said above.

The reason is - *xpt[1] is dereferencing a memory that is not even pointing to any elements of the array. This is undefined behavior.

123456789XXXXXXXXXX
^        ^
|        |
xpt[0]   xpt[1]

Here 1234.... denotes the elements of the array and xpt[1] points to out of the array.

Also array subscripts ( [] ) has higher precedence than dereference( * ). As a result when you write *xpt[1] it will first calculate xpt[1] and then try to get it's value, which is causing undefined behavior in your program.

Also to give you a better intuitive idea about how to understand this - Pointers operations are dictated by what it points to. Here when you declared

int (*xpt)[9] = &x;

it is saying that xpt is a pointer to an int array of 9 elements. Now you initialize with the address of x . Now think what it points to ? It is the array object x . So what will it point to if we do this xpt[1] ? Next array object (if any). So that's why we get to the address first and then dereference it to get to the array (*xpt) and now use array subscript to get the correct elements.

int* xpt = &x

is something compiler will complain about. It is assigning type int(*)[9] to int* - this is wrong. The type matters for pointers - that's why compiler will complain.

One more interesting thing you may ask why *xpt[0] is 11 not 22 or 33 etc?

The thing is xpt[0] is the array to which xpt was pointing to. The array xpt[0] converts (decays) into pointer to first element ( xpt[0][0] ) of the array( xpt[0] ), and then you dereferenced ( *xpt[0] )it. That's why you got the first element of the array as the value.

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