Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array Pointer not returned the expected value

Tags:

arrays

c

pointers

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

like image 990
Unhandled Exception Avatar asked Jan 20 '26 03:01

Unhandled Exception


1 Answers

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.

like image 134
user2736738 Avatar answered Jan 21 '26 22:01

user2736738