length - std array c++



Por que o `& array` e` array` estão apontando para o mesmo endereço? (2)

Até agora, pensei que um array é o mesmo que um ponteiro. Mas eu encontrei um caso estranho:

código

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;

saída

0x7ffeed730ad0
0x7ffeed730ad0
0x7ffeed730ad0

0x7f906d400340
0x7ffeed730a30
0x7f906d400340

Como você pode ver, array e &array têm o mesmo valor. Mas pArray e &pArray têm um valor diferente. Se array é o mesmo que ponteiro, o endereço do array deve ser diferente do array. Como array e array podem ser os mesmos? Se array e &array são iguais, qual é o endereço da memória que contém os valores da matriz?

https://src-bin.com


Answer #1

Uma matriz de Xs tem que se comportar como um ponteiro para uma lista contígua de Xs na memória, muito parecida com um ponteiro. No entanto, em nenhum lugar está escrito onde a memória que armazena esses dados deve ser seu próprio endereço e gravável. No caso de um ponteiro explícito, há uma nova alocação para esse endereço (neste caso, a pilha). No entanto, para uma matriz, na pilha, o compilador já sabe onde o conteúdo está, portanto, nenhuma nova alocação é necessária.

Como conseqüência, não é seguro tratá-lo como um ponteiro, sem indexação. por exemplo:

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

Answer #2

array simples decai para um ponteiro para seu primeiro elemento, é igual a &array[0] . O primeiro elemento também começa no mesmo endereço do próprio array. Por isso, &array == &array[0] .

Mas é importante notar que os tipos são diferentes:

  • O tipo de &array[0] é (no seu exemplo) int* .
  • O tipo de &array é int(*)[5] .

A relação entre &array[0] e &array pode ser mais fácil se eu mostrar um pouco mais "graficamente" (com ponteiros adicionados):

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

As coisas são diferentes com ponteiros embora. O ponteiro pArray está apontando para alguma memória, o valor de pArray é a localização dessa memória. Isso é o que você obtém quando usa o pArray . Também é o mesmo que &pArray[0] .

Quando você usa o &pArray você obtém um ponteiro para o ponteiro . Ou seja, você obtém o local (endereço) da variável pArray si. Seu tipo é int** .

Um pouco gráfico com o ponteiro pArray seria algo como isto

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

[Observe o ... no final do "array", porque os ponteiros não retêm nenhuma informação sobre a memória para a qual ele aponta. Um ponteiro está apontando apenas para um local específico, o "primeiro" elemento da "matriz". Tratar a memória como uma "matriz" depende do programador.]





pointers