1

I found codes that uses address operator to address. See below example codes.

int arr[4] = { -1, -1, -1, -1 };
int arr2[4] = { 0, 0, 0, 0 };

memcpy(arr, &arr2, sizeof(arr2)); // & operator to arr2

When I check values of (arr, &arr) with printf, both addresses are equal.

And I have no idea why this codes are valid. (I'm using C++ 14)

RAMSA
  • 13
  • 3
  • 2
    `&arr2` is the address of the array as a whole. `arr2` by itself decays to the address of the array's first element. It so happens that the array and its first element are located at the same address. – Igor Tandetnik Feb 23 '23 at 00:54
  • Arrays naturally *decay* to pointers to their first element. So e.g. `arr` is the same as `&arr[0]`, and has the type `int *`. Same when using plain `arr2`. But `&arr2` is a pointer to the array itself, and will have the type `int (*)[4]`, which really is incompatible with the type `int *`. With that said, both `&arr[0]` and `&arr` "luckily" happens to be the same location. – Some programmer dude Feb 23 '23 at 00:59
  • Short answer - because language allows that – Slava Feb 23 '23 at 01:01
  • Also note that because of the array to pointer decay, it's very hard to pass arrays to functions. As an argument the declaration `int arr[]` (or even using a size like `int arr[4]`) is treated as `int *arr`. If you then use the pointer-to operator on the argument variable, you will get a pointer to that variable (which have the type `int **`), not to the original array. – Some programmer dude Feb 23 '23 at 01:02
  • 1
    And in C++, please don't use plain arrays if you can avoid it. If the size is fixed and known at compile-time (and not too big) then use `std::array` (as in `std::array`). Otherwise use `std::vector`. This will solve a lot of problems you might encounter when using plain C-style arrays. – Some programmer dude Feb 23 '23 at 01:04
  • Those replies are clear and helpful. Thanks for replies and additional explanations! – RAMSA Feb 23 '23 at 01:21

1 Answers1

3

Why can I use an address of address without any errors?

Because std::memcpy accepts arguments of type void* (const qualifier aside), and all object pointers are implicitly convertible to void*.

Although arr itself isn't a pointer, it is an array, and arrays implicitly convert to pointer to first element, which implicitly converts to void*.

&arr2 is a pointer to an array which implicitly converts to void*.

When I check values of (arr, &arr) with printf, both addresses are equal.

The memory location of the first element of an array is the same as the memory location of the array.

eerorika
  • 232,697
  • 12
  • 197
  • 326