3

I met a weird thing when I tried to understand the pointer tp this array

#include <iostream>

int main() {
    using namespace std;

    short tell[3]{1, 2, 3};

    short (*pas)[3] = &tell;

    cout << (*pas)[2] << endl;
    cout << *pas[2] << endl;

    cout << endl;

    return 0;
}

I got two different values for the two outputs.

The first one is correct, which is 3.

However, for the second one, it seems it returns a random number which is different every time.

What is the difference between these two?

ZygD
  • 22,092
  • 39
  • 79
  • 102
Nicolas H
  • 535
  • 3
  • 13
  • 1
    second one is undefined behavior. First one is equivalent to `pas[0][2]` second to `pass[2][0]` – Marek R Feb 07 '21 at 16:44
  • Just enable warnings with `-Wall`. You'll get "warning: array subscript 6 is outside array bounds of 'short int [3]' [-Warray-bounds] 11 | cout << *pas[2] << endl;" – JHBonarius Feb 07 '21 at 16:46

2 Answers2

3

You declared a pointer to a whole array

short (*pas)[3] = &tell;

So to get the pointed object (array) you have to dereference the pointer like

*pas

Now this expression yields a lvalue reference to the array tell. So you may apply the subscript operator to access elements of the array

cout << (*pas)[2] << endl;

The postfix subscript operator has a higher priority than the unary operator *.

that is this expression

*pas[2]

is equivalent to the expression

*( pas[2] )

It means you are trying to access an object (array) beyond the allocated array that results in undefined behavior.

If you had a two=dimensional array like for example

short tell[3][3] =
{ { 1, 2, 3 },
  { 4, 5, 6 },
  { 7, 8, 9 }
};

And initialized the pointer pas like

short (*pas)[3] = tell;

the the expression pass[2] would yield the third element of the array that is { 7, 8, 9 } In this case you may apply one more subscript operator to access an element of the array like for example

pass[2][2]

that contains the value 9.

The above expression also can be rewritten without the subscript operator like

*( *( pass + 2 ) + 2 )
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

A simple example can be :

int *ptr[10];

This is an array of 10 int* pointers, not as you would assume, a pointer to an array of 10 ints

int (*ptr)[10];

This is a pointer to an array of 10 int

It is I believe the same as int *ptr; in that both can point to an array, but the given form can ONLY point to an array of 10 ints

Also you can check this example.

Frightera
  • 4,773
  • 2
  • 13
  • 28