为什么`&array`和`array`指向相同的地址?

时间:2019-02-21 12:34:15

标签: c++ arrays pointers

直到现在,我还认为数组与指针相同。但是我发现了一个奇怪的情况:

代码

int array[5] = { 10,11,12,13,14};

std::cout << array << std::endl;
std::cout << &array << std::endl;
std::cout << &array[0] << std::endl;

int *pArray = new int[5];

std::cout << pArray << std::endl;
std::cout << &pArray << std::endl;
std::cout << &pArray[0] << std::endl;

输出

0x7ffeed730ad0
0x7ffeed730ad0
0x7ffeed730ad0

0x7f906d400340
0x7ffeed730a30
0x7f906d400340

您会看到array&array的值相同。但是pArray&pArray具有不同的值。如果数组与指针相同,则数组的地址应与数组不同。 array&array如何相同?如果array&array相同,那么保存数组值的内存地址是什么?

2 个答案:

答案 0 :(得分:79)

平原array衰减为其第一个元素的指针,它等于&array[0]。第一个元素也恰好从与数组本身相同的地址开始。因此&array == &array[0]

但是必须注意,类型是不同的:

  • (在您的示例中)&array[0]的类型为int*
  • &array的类型为int(*)[5]

&array[0]&array之间的关系如果更“图形化地”显示(添加了指针),则可能会更容易:

+----------+----------+----------+----------+----------+
| array[0] | array[1] | array[2] | array[3] | array[4] |
+----------+----------+----------+----------+----------+
^
|
&array[0]
|
&array

尽管指针有所不同。指针pArray指向某个内存,pArray的值是该内存的位置。这就是使用pArray时得到的。它也与&pArray[0]相同。

使用&pArray时,您会得到一个指向该指针的指针 。也就是说,您获得了变量pArray本身的位置(地址)。其类型为int**

使用指针pArray进行一些图形化处理

+--------+       +-----------+-----------+-----------+-----------+-----------+-----+
| pArray | ----> | pArray[0] | pArray[1] | pArray[2] | pArray[3] | pArray[4] | ... |
+--------+       +-----------+-----------+-----------+-----------+-----------+-----+
^                ^
|                |
&pArray          &pArray[0]

[注意“数组”末尾的...,这是因为指针不保留有关其指向的内存的信息。指针仅指向特定位置,即“数组”的“第一个”元素。将内存视为“数组”取决于程序员。]

答案 1 :(得分:1)

X的数组的行为必须类似于指向内存中X的连续列表的指针,就像指针一样。但是,在存储该数据的内存的任何地方都不能写它自己的地址和可写j。在使用显式指针的情况下,将为该地址(在本例中为堆栈)分配一个新的地址,但是对于数组,在堆栈上,编译器已经知道了内容的位置,因此不需要新的分配。

因此,将其视为没有索引的指针是不安全的。例如:

pArray = nullptr; // This is a memory leak, unless a copy is taken, but otherwise fine.
array = nullptr; // This is will make the compiler upset