2

In C++ name of the array without a bracket, is a pointer to the first element of the array. However, I couldn't realize how the following code works

int main()
{
    int x[] = {1, 2, 3, 4};
    cout << "x = " << x << endl;    
    cout << "&x = " << &x << endl;
    cout << "*(&x) = " << *(&x) << endl;
    cout << "*x = " << *x << endl;
    cout << "**(&x) = " << **(&x) << endl;
}

and this is the output

x = 0x7ffd179e9060
&x = 0x7ffd179e9060
*(&x) = 0x7ffd179e9060
*x = 1
**(&x) = 1

What I don't understand is

  1. why does x = &x = 0x7ffd179e9060?
  2. if x = &x = 0x7ffd179e9060, then must be *x = *(&x) while *x=1 and *(&x) = 0x7ffd179e9060
  3. Why pointer to pointer **(&x) = 1 is working here?

Thanks in advance.

Question Why are &array and array pointing to the same address?is not an answer to my question.

6
  • 2
    "In C++ name of the array without a bracket, is a pointer to the first element of the array.": This is wrong and probably causes your confusion. There should be a hundred duplicates on this here. Commented Oct 9, 2023 at 5:23
  • x and &x are not the same, they are both pointers, pointing at the same address (which is why they print the same value) but the first is a pointer to the first element, and the second is a pointer to the array. In other words they are both pointers but the type is different, Commented Oct 9, 2023 at 5:34
  • This also explains why *x and *(&x) are different, and why **(&x) works. Commented Oct 9, 2023 at 5:36
  • Near duplicate of: stackoverflow.com/q/8916656/179910 Commented Oct 9, 2023 at 6:19
  • Side note this way of working with arrays (and naked pointers) is more for "C" *And yes I know this is still being taught as part of datastructure classes). But in C++ use std::array or std::vector to avoid pointer decay of arrays (the situation where you only have the pointer to the first element of an array, but all size information is lost) Commented Oct 9, 2023 at 6:24

2 Answers 2

6

In C++ name of the array without a bracket, is a pointer to the first element of the array

It may seem like this, but this isn't really what is happening. The name of an array is the name of the array and denotes the array. What actually happens is that whenever you use an array-typed expression in an rvalue context, it get implicitly converted into a pointer to the array's first element.

Since most contexts are rvalue contexts, it may seem like the array is always the same as a pointer to the first element, but the details sometimes matter. In particular, the operand of a unary & is not an rvalue context, so when you say &x you get a pointer to the array as a whole. Thus x and &x end up appearing to have the same value, and the actual bit pattern of the pointer is the same; all that is different is the type.

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

4 Comments

In sizeof(array), there's no conversion either, so you get the size of the array, not the size of a pointer.
sizeof, like &, is not an rvalue context. Neither are a number of other things.
Why pointer to pointer **(&x) = 1 is working here?
The & gives you a pointer to the array, which the first * removes (giving you back the array). That is then implicitly converted to a pointer to the array's first element (operand of * is an rvalue context), and that second * give you the array's first element. The = then assigns to value 1 to that first array element.
4

&x, &(x) and (&x) are all the same.

As an expression, plain x is the same as &x[0]. Which is very different from &x.

&x is a pointer to the array itself, and will have the type int (*)[4]. &x[0] is a pointer to the first element of the array and will have the type int*.

The reason both &x and &x[0] points to the same location is easy to understand if we draw it:

+------+------+------+------+
| x[0] | x[1] | x[2] | x[3] |
+------+------+------+------+
^
|
&x
|
&x[0]

As you noticed, and which can easily be seen in the drawing above, both &x and &x[0] are pointing to the same location. But they have different types.

Also, for any pointer or array p and index i, the expression p[i] is exactly equal to *(p + i). From this it's possible to deduce that *p is the same as p[0]. So *(&x) is the same as (&x)[0] which is the same as x.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.