5

The following code:

#include<iostream>

int main (void) {

    int lista[5] = {0,1,2,3,4};
    std::cout << lista << std::endl;
    std::cout << &lista << std::endl;
    std::cout << lista+1 << std::endl;
    std::cout << &lista+1 << std::endl;
    std::cout << lista+2 << std::endl;
    std::cout << &lista+2 << std::endl;
    std::cout << lista+3 << std::endl;
    std::cout << &lista+3 << std::endl;

    return (0);
}

Outputs:

0x22ff20
0x22ff20
0x22ff24
0x22ff34
0x22ff28
0x22ff48
0x22ff2c
0x22ff5c

I understood that an array is another form to express a pointer, but we cannot change its address to point anywhere else after declaration. I also understood that an array has its value as the first position in memory. Therefore, 0x22ff20 in this example is the location of the array's starting position and the first variable is stored there.

What I did not understand is: why the other variables are not stored in sequence with the array address? I mean, why lista+1 is different from &lista+1. Should not they be the same?

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
user10906383
  • 323
  • 1
  • 8
  • 5
    *I understood that an array is another form to express a pointer*. It is not. Do not think of an array as a pointer. The are completely different types. An array will decay to a pointer is many situations but it is not one. – NathanOliver Feb 22 '19 at 19:23
  • 1
    Useful reading: [What is array decaying?](https://stackoverflow.com/questions/1461432/what-is-array-decaying) – user4581301 Feb 22 '19 at 19:25
  • 3
    Wrong duplicate, the question is very simple and warrants it's own answer. – SergeyA Feb 22 '19 at 19:28
  • 1
    `&lista+1` is not the second element or `lista`. It would be the start of the 2nd `int[5]` array if `lista` was part of an array of `int[5]`s. – François Andrieux Feb 22 '19 at 19:32

2 Answers2

11

In pointer arithmetic, types matter.

It's true that the value is the same for both lista and &lista, their types are different: lista (in the expression used in cout call) has type int* whereas &lista has type int (*)[5].

So when you add 1 to lista, it points to the "next" int. But &lista + 1 points to the location after 5 int's (which may not be a valid).

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
P.P
  • 117,907
  • 20
  • 175
  • 238
  • 2
    Nit: In C++17, the memory model changed so that the two pointers don't actually have the same value - they just happen to represent the address of the same byte. One consequence of this is that in order to `reinterpret_cast` from one to the other, you need `std::launder`, as the types `T` and `T[N]` are not pointer-interconvertible with each other. – Brian Bi Feb 22 '19 at 19:41
3

Answering the question as asked:

std::cout << &lista+1 << std::endl;

In this code you take the address of array lista and add 1 to obtained answer. Given the sizeof of the array is sizeof(int) * 5, which means when you increment a pointer to it by 1 you add sizeof(int) * 5 to the pointer address, you end up with a number you see.

SergeyA
  • 61,605
  • 5
  • 78
  • 137