0

Why can't we directly assign the address of a 2D array to a pointer?

Is there any way we can assign it in a single line, not with the help of a for loop?

Is there any other better approach?

// Array of 5 pointers to an array of 4 ints 

int (*Aop[5])[4];

for(int i = 0;i<5;i++) 
{
    Aop[i] = &arr2[i];  //Works fine
} 
 
//Why this doesn't work int 
int (*Aop[5])[4] = &arr2[5][4]
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Sanjeev
  • 115
  • 7
  • Array initializers have to be literals, you can't assign arrays to each other. – Barmar Mar 03 '21 at 17:03
  • What does `int (*Aop[5])[4];` mean here? Your intent isn't clear. Pointers to arrays of "fixed" sizes are somewhat useless because there's no bounds checking anyway. – tadman Mar 03 '21 at 17:06
  • When asking questions like this please focus on one of C or C++. Their behaviour can differ significantly. – tadman Mar 03 '21 at 17:07
  • If you used `std::vector` you *could* just assign them, and you wouldn't have to worry about raw pointers and manual copying. Which is also why you shouldn't tag *both* C and C++ because if you are asking about C the answer is obviously different than in C++ – Cory Kramer Mar 03 '21 at 17:10

2 Answers2

2

This declaration

int (*Aop[5])[4];

does not declare a pointer. It is a declaration of an array of 5 pointers to one-dimensional arrays of the the int[4].

Arrays do not have the assignment operator. However you could initialize it in its declaration as for example

int (*Aop[5])[4] = { &arr2[0], &arr2[1], &arr2[2], &arr2[3], &arr2[4] };

or

int (*Aop[5])[4] = { arr2, arr2 + 1, arr2 + 2, arr2 + 3, arr2 + 4 };

Here is a demonstrative program.

#include <stdio.h>

int main(void) 
{
    enum { M = 5, N = 4 };
    
    int arr2[M][N] =
    {
        { 1, 1, 1, 1 },
        { 2, 2, 2, 2 },
        { 3, 3, 3, 3 },
        { 4, 4, 4, 4 },
        { 5, 5, 5, 5 }
    };
    
    int (*Aop[M])[N] = { arr2, arr2 + 1, arr2 + 2, arr2 + 3, arr2 + 4 };
    
    for ( size_t i = 0; i < M; i++ )
    {
        for ( size_t j = 0; j < N; j++ )
        {
            printf( "%d ", ( *Aop[i] )[j] );
        }
        putchar( '\n' );
    }
    
    return 0;
}

The program output is

1 1 1 1 
2 2 2 2 
3 3 3 3 
4 4 4 4 
5 5 5 5

If you need to declare a pointer to the array arr2 then you should bear in mind that array designators are implicitly converted (with rare exceptions) to pointers to their first elements. The array arr2 has elements of the type int[4]. So a pointer to an object of this type will have the type int ( * )[4]. So you can write

int (*Aop )[4] = arr2;

Here is another demonstrative program that uses pointers in for loops to output elements of the array arr2.

#include <stdio.h>

int main(void) 
{
    enum { M = 5, N = 4 };
    
    int arr2[M][N] =
    {
        { 1, 1, 1, 1 },
        { 2, 2, 2, 2 },
        { 3, 3, 3, 3 },
        { 4, 4, 4, 4 },
        { 5, 5, 5, 5 }
    };
    
    int (*Aop )[N] = arr2;
    
    for ( int ( *p )[N] = Aop; p != Aop + M; ++p )
    {
        for ( int *q = *p; q != *p + N; ++q )
        {
            printf( "%d ", *q );
        }
        putchar( '\n' );
    }
    
    return 0;
}

Again the program output is

1 1 1 1 
2 2 2 2 
3 3 3 3 
4 4 4 4 
5 5 5 5
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

These work just fine to declare a pointer to the entire array:

int (*Ap)[4] = arr2;

int (*Bp)[5][4] = &arr2;

The size of an array only appears in its declaration, and NOT when passing it around. arrs[5][4] is an out-of-bounds array access (out of bounds by a whole row and a whole column, so you can't even use legally it as the past-the-end reference by avoiding lvalue-to-rvalue conversion)

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720