why the address of dynamic array is different from the first element address?

Viewed 239
#include<iostream>
using namespace std;


int main()
{
    int* q = new int[3];
    cout << &q[0] << endl;
    cout << q << endl;  
    cout << &q << endl; // why here is different?

    int p[3];
    cout << &p[0] << endl;
    cout << p << endl;
    cout << &p << endl;



    return 0;
}

here is my code, I use new to create dynamic arrays, but the array address really confused me, why &q is different?

4 Answers

The expression &q is a pointer to the variable q, which is indeed different from where q is pointing.

You could look at it like this:

+----+     +---+     +------+------+------+
| &q | --> | q | --> | q[0] | q[1] | q[2] |
+----+     +---+     +------+------+------+

On the other hand p is an array, where &p is a pointer to the array itself:

+----+     +------+------+------+
| &p | --> | p[0] | p[1] | p[2] |
+----+     +------+------+------+

There's also a very large semantic difference between &q and &p: Their types.

The type of &q is int**, while &p is of the type int (*)[3].

This also explains why &p and &p[0] seems to be the same, they both point to the same location. But here too there's a semantic difference, the type of &p[0] is int*.

Lastly, arrays can decay to a pointer to its first element, which means that p is the same as &p[0], and even have the same type.

Because q is a pointer, it doesn't decay to a pointer like an array would. In this case &q means the pointer to the pointer q, whereas &q[0] means the pointer to q dereferenced, in other words q itself.

p is an array. q is a pointer. An array contains the actual data. Therefore a pointer &p to the array p points directly to the data.

The pointer q is a variable that contains the address of the dynamic array. The address of the pointer is different to the address of the data.

This code snippet describes what happens:

#include<iostream>
using namespace std;


int main()
{
    // new int[3] creates an array
    // int *q creates a pointer pointing to the array
    int* q = new int[3];
    cout << &q[0] << endl;
    cout << q << endl;  
    cout << &q << endl; // why here is different?

    // int p[3] creates an array
    int p[3];
    // int *pp creates a pointer pointing to the array
    int *pp = p;
    cout << &pp[0] << endl;
    cout << pp << endl;
    cout << &pp << endl;



    return 0;
}

The difference is that you can't access the dynamic array in the first case. It doesn't have a name. It can only be accessed through the pointer p.

In the second case the array has a name p and you can access it directly or through the pointer pp.

The address of dynamic array is the q. &q is the address of address of dynamic array.

Related