The problem is that the initialized object and the initializer have different pointer types and there is no implicit conversion from one pointer type to another.
In this declaration
int (*p1)[5] = arr;
the initialized object has the type int ( * )[5]
while the initializer has the type int *
due to the implicit conversion of the array designator to a pointer to its first element.
You have to write
int (*p1)[5] = &arr
Or for example
int ( *p1 )[5] = reinterpret_cast<int ( * )[5]>( arr );
Here is a demonstrative program.
#include <iostream>
int main()
{
int arr[5] = {1,2,3,4,5};
int ( *p1 )[5] = reinterpret_cast<int ( * )[5]>( arr );
std::cout << "sizeof( *p1 ) = " << sizeof( *p1 ) << '\n';
return 0;
}
The program output is
sizeof( *p1 ) = 20
Objects can have equal values but different types.
Consider an another case.
Let's assume that you have an object of a structure type
struct A
{
int x;
} a;
in this case &a
and &a.x
have the same values but the types of the expressions are different. You may not write for example
int *p = &a;
the compiler will issue an error. But you can write
int *p = ( int * )&a;
or
int *p = reinterpret_cast<int *>( &a );
Here is a demonstrative program.
#include <iostream>
#include <iomanip>
int main()
{
struct A
{
int x;
} a = { 10 };
std::cout << std::boolalpha << ( ( void * )&a.x == ( void * )&a ) << '\n';
int *p = reinterpret_cast<int *>( &a );
std::cout << "*p = " << *p << '\n';
return 0;
}
The program output is
true
*p = 10
As for your one more question in a comment
Can you decode this in simple language to understand int** p = new
int*[5];
then in this expression with the operator new
new int*[5]
there is allocated memory for an array with 5 elements of the type int *
. The expression returns a pointer to the first element of the array. A pointer to an object of the type int *
(the type of elements of the allocated array) will have the type int **
.