4

As far as I know, in some contexts, an array is converted into a pointer to its first element:

int a[5];
int * p;

p = a;

Following this approach and considering I can assign an array to a pointer, why can't I assign a bidimensional array to a pointer to a pointer?

int a[5][5];
int ** q;

q = a;

However, I can assign an array of pointers to a pointer to a pointer:

int * p[5];
int ** q;

q = p;

If an array is converted into a pointer to its first element, when q = a happens in the second example, a should be a pointer to a[0] and a[0] should be a pointer to a[0][0], right?

Besides, I don't get an error if I do:

cout << **a;

Thanks in advance and I hope you can help me to understand.

Mark Renton
  • 101
  • 2
  • 7
  • 3
    An array is not a pointer (it decays to it in some contexts _ namely function calls). Similarly a 2D array is not a pointer to a pointer. And a 2D array is not an array of pointers, those are different too – quantdev Aug 16 '14 at 21:01
  • You cannot assign it, because you are not only doing the assignment to a variable but you are also allocating memory of size[5][5]. The way you allocate memory to pointer of pointer or int **q is different. You first allocate memory like this: int **q = new int *[5]; for(int i= 0; i < 5; i++){q[i] = new int[5];} – Juniar Aug 16 '14 at 21:44

4 Answers4

6

The problem is that an array int a[5][5]; stores 25 consecutive int.

A pointer to arrays/pointers like int **q; expects to find an array of consecutive pointers to int.

This is why the assignment you want to do is not possible.

Chnossos
  • 9,971
  • 4
  • 28
  • 40
Christophe
  • 68,716
  • 7
  • 72
  • 138
3

a multi-dimensional array can be assigned to a single pointer

int a[5][5];
int *p = a;

because the memory is allocated as a single block organized by row.

a = a11 a12 a13
    a21 a22 a23    

a = a11 a12 a13 a21 a22 a23 
Massimo Costa
  • 1,864
  • 15
  • 23
1

For multidimensional arrays if you want to point into single (scalar) value, then you should use the following declarations:

int a[5][5];
int (*q)[5]; /* pointer to five-element array of basic type int */

q = a;
q[0][0]; /* equivalent to a[0][0] */

where 5 is the "column" size (next to left-most "row" size). In general for more dimensions remember that rule is that only left-most size is replaced with (*q) part of declarator.

In fact when you write function, that has multidimensional array parameter, then for compiler it's considered as in above form, for instance:

int foo(int a[5][5]) { ... }

is effectively replaced with:

int foo(int (*a)[5]) { ... }
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Grzegorz Szpetkowski
  • 36,988
  • 6
  • 90
  • 137
1

For it would be more clear let's consider your first example

int a[5];
int * p;

p = a;

In can be rewritten the following way

T a[5];
T * p;

p = a;

where T is some type.

What is a two-dimensional array in C/C++? It is an array elements of which in turn are one-dimensional arrays.

So this definition

int a[5][5];

can be rewritten as

T a[5];

where T has type int[5]

And we have

T a[5];
T * p;

p = a;

where T as we already know is int[5] So p has type of pointer to array of type int[5] and has to be defined as

int ( *p )[5];

p = a;

int ( * )[5] and int ** are two different types.

As for this code

int * p[5];
int ** q;

q = p;

when here T is int * so p is defined as T *p that in turn is int **p

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335