3

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]?

3
  • Since xpt is an array pointers (I assume) - xpt is a pointer to array of 9 ints. Don't assume, but find the docs and verify. Commented Jan 24, 2018 at 18:12
  • I have yet to find a single reference that does a very good job explaining pointers in various scenarios. Usually I have to find various links and piece together an explanation. If you have reference to a URL which does a good job, please post. Commented Jan 24, 2018 at 18:21
  • 1
    For this specific issue you can use cdecl. It is reading the docs for you :) But there is so-called Spiral Rule Commented Jan 24, 2018 at 18:22

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

3 Comments

in fact your declaration of xpt was a clue - you did int (*xpt)[9] = &x; for the same reason, except the compiler complained when you tried int *xpt[9] = &x;
@pm100.: i am still editing - including this too...Please give me some time.
@pm100.: check please

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.