user7070057
user7070057

Reputation:

a qestion about pointers to pointers

double a=4;
double *x=&a;
double **y=&x;
cout <<x<<endl<<(y+1)<<endl<<(y+1)[0]<<endl<<y[1];

If I run the above C++ code, the output will be:

0x28fef0

0x28fef0

0

0

I know the value of x is the address of variable a, and the value of y is the address of variable x. but how come x=y+1? what do y+1, (y+1)[0] and y[1] mean? Thanks for any help!

Upvotes: 4

Views: 128

Answers (3)

Juan
Juan

Reputation: 430

Things we know about the variables:

  • a is a double

  • &a is a pointer to a (double *)

  • x is a pointer to element/s of type double.

  • x is initialized to point to a, it stores a adress (&a)

  • &x is a pointer to x (double **)

  • y is a pointer to pointer/s to double

  • y is initialized to point to x, it stores x address (&x)

Now, about the expressions:

  • y + 1 increments the pointer in the size of the element pointed to, this is, the size of a pointer.

  • y [0] is the first element of the array pointed to by y. y points to a scalar, which behaves in this case as an array of size 1 element. It is totally equivalent to dereferencing y (*y). So, y [0] == *y == x

  • Similarly, y [1] == *(y + 1). As there is no second element in the "array" pointed to by y, this expression triggers undefined behavior. Ideally, it would result in an exception, but undefined means anything. It may as well destroy the Universe, and it would be a compliant implementation.

  • (y + 1)[0] increments y and derreferences it, so (y + 1)[0] == *(y + 1) == y [1]. It's equivalent to the previous one, triggering the same undefined behaviour.

Now, the address of a variable is totally implementation dependent. It may also be different in every execution.

These variables are automatic variables, which are stored in the stack.

In all implementations I know of, the stack starts in a high address and grows downwards.

This means that, tipically, all automatic variables in the same block are stored together in decreasing address order.

In your case, the compiler allocates the variables in the stack in the same order they are declared.

The result is that &a > &x > &y

The compiler may introduce gaps in the middle for alingment purposes. In this case, it either does not so, or it takes it into account in pointer arithmetic.

So, as y points to x, if you add 1 to y, you get the address of a, which is located next to x.

x also points to a, so you may feel tempted to say that y + 1 == x

In what comes to raw addresses this is true, but not when it comes to pointers, because they are not of the same type.

y + 1 is still a double ** while x is a double *

We know that (y + 1)[0] == y [1]. While x [0] == a, y [1] tries to interpret the value of a as a pointer to double. You could say in this case that y [1] == (double *) a

Looks like all this undefined behaviour, in this implementation, results in interpreting the value 4.0 as a null pointer, printed out as 0

Upvotes: 0

GoodDeeds
GoodDeeds

Reputation: 8507

  • a is an integer variable whose value is 4.
  • x is a pointer to an integer which contains the address of a.
  • y is a pointer to an integer pointer, i.e., it points to a variable which is an integer pointer itself, and here, its value is the address of x.

Now,

  • When you print the value of x, it prints out the address it contains, i.e., the address of a.
  • y contains the address of x. y+1 is the address next to the address stored in y. Here, by coincidence, it turns out that the address stored in y was just before the address of a, and hence, y+1=x. There is no reason for this to happen.
  • (y+1)[0] and y[1] are the same as *(y+1). This dereferences, i.e., gives the value stored at, the address next to y, which is undefined behaviour.

Upvotes: 0

NPE
NPE

Reputation: 500227

how come x=y+1?

By accident. Your compiler happens to lay out x and y in memory such that one immediately follows the other. It is under no obligation to do that, so you can't rely on this behaviour.

Note that dereferencing y+1, for example through (y+1)[0], y[1] or *(y+1), also has undefined behaviour.

Upvotes: 8

Related Questions