Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array of pointers to an array of fixed size

Tags:

arrays

c

I tried to assign two fixed-size arrays to an array of pointers to them, but the compiler warns me and I don't understand why.

int A[5][5]; int B[5][5]; int*** C = {&A, &B}; 

This code compiles with the following warning:

warning: initialization from incompatible pointer type [enabled by default]

If I run the code, it will raise a segmentation fault. However, if I dynamically allocate A and B, it works just fine. Why is this?

like image 990
Viridya Avatar asked May 20 '16 14:05

Viridya


People also ask

Are arrays in C fixed size?

Arrays a kind of data structure that can store a fixed-size sequential collection of elements of the same type.

What is the size of a pointer to an array?

The pointer ptr, and all pointers, are 8 bytes, because they hold addresses, which are 8 bytes, or 64 bits. Assigning any address to an array variable is not allowed.

Is the size of an array fixed?

The length of an array is established when the array is created. After creation, its length is fixed.

Can pointers point to array?

Pointer to an array points to an array, so on dereferencing it, we should get the array, and the name of array denotes the base address. So whenever a pointer to an array is dereferenced, we get the base address of the array to which it points.


2 Answers

If you want a declaration of C that fits the existing declarations of A and B you need to do it like this:

int A[5][5]; int B[5][5]; int (*C[])[5][5] = {&A, &B}; 

The type of C is read as "C is an array of pointers to int [5][5] arrays". Since you can't assign an entire array, you need to assign a pointer to the array.

With this declaration, (*C[0])[1][2] is accessing the same memory location as A[1][2].

If you want cleaner syntax like C[0][1][2], then you would need to do what others have stated and allocate the memory dynamically:

int **A; int **B; // allocate memory for A and each A[i] // allocate memory for B and each B[i] int **C[] = {A, B}; 

You could also do this using the syntax suggested by Vlad from Moscow:

int A[5][5]; int B[5][5]; int (*C[])[5] = {A, B}; 

This declaration of C is read as "C is an array of pointers to int [5] arrays". In this case, each array element of C is of type int (*)[5], and array of type int [5][5] can decay to this type.

Now, you can use C[0][1][2] to access the same memory location as A[1][2].

This logic can be expanded to higher dimensions as well:

int A[5][5][3]; int B[5][5][3]; int (*C[])[5][3] = {A, B}; 
like image 106
dbush Avatar answered Oct 05 '22 14:10

dbush


Unfortunately there's a lot of crappy books/tutorials/teachers out there who will teach you wrong things....

Forget about pointer-to-pointers, they have nothing to do with arrays. Period.

Also as a rule of thumb: whenever you find yourself using more than 2 levels of indirection, it most likely means that your program design is fundamentally flawed and needs to be remade from scratch.


To do this correctly, you would have to do like this:

A pointer to an array int [5][5] is called array pointer and is declared as int(*)[5][5]. Example:

int A[5][5]; int (*ptr)[5][5] = &A; 

If you want an array of array pointers, it would be type int(*[])[5][5]. Example:

int A[5][5]; int B[5][5]; int (*arr[2])[5][5] = {&A, &B}; 

As you can tell this code looks needlessly complicated - and it is. It will be a pain to access the individual items, since you will have to type (*arr[x])[y][z]. Meaning: "in the array of array pointers take array pointer number x, take the contents that it points at - which is a 2D array - then take item of index [y][z] in that array".

Inventing such constructs is just madness and nothing I would recommend. I suppose the code can be simplified by working with a plain array pointer:

int A[5][5]; int B[5][5]; int (*arr[2])[5][5] = {&A, &B}; int (*ptr)[5][5] = arr[0]; ... ptr[x][y][z] = 0; 

However, this is still somewhat complicated code. Consider a different design entirely! Examples:

  • Make a 3D array.
  • Make a struct containing a 2D array, then create an array of such structs.
like image 45
Lundin Avatar answered Oct 05 '22 14:10

Lundin