# Mulitdimensional Arrays and Pointers

• 11-02-2012
Mr.Lnx
Mulitdimensional Arrays and Pointers
Hello to all.

I can't understand why this snippet

Code:

```#include<stdio.h> int main(void) {         int arr2d[2][4] = { { 0 , 1 , 2 , 3 } , {4, 5 , 6 , 7}} , (*p)[4] , i=0;                 for( p = &arr2d[0]; p < &arr2d[2]; p++)         {                 printf(" %d %d " , (*p)[i] , arr2d[0][0] );         }                 return 0; }```
Will advance the pointer Number_of_columns * sizeof(int) .

Code:

``` #include<stdio.h> int main(void) {         int arr2d[2][4] = { { 0 , 1 , 2 , 3 } , {4, 5 , 6 , 7}} , *p ;                 for( p = arr2d[0]; p < arr2d[1] + 4 ; p++)         {                 printf("%d " , *p );         }                 return 0; }```
Which will advance pointer (p) 4 bytes (assuming in my system that int has 4 bytes size ) . The first snippet will process an column but the second a row. I know that... but I can't understand why in the second situation will advance the pointer with this size . (#COLUMNS * sizeof(int) ) . Due to & in front of arr2d[0] ?
Yes but if we have p = &arr2d[0] ... arr2d[0] is a pointer , hence &arr2d[0] is a pointer to pointer but p is declared as a signle pointer without some object by the compiler. arr2d[0] is a pointer to arr2d[0][0] . Why this ?

(*p)[4] is a double pointer declaration??? (cheating) .
• 11-02-2012
Salem
Code:

```struct foo {     int arr[10]; }; struct foo arr[10]; struct foo *p; for ( p = arr ; p < arr+10 ; p++ ) { }```
Do you understand by how much p++ advances through memory.

The same applies when you have an array containing an array (which is what 2D arrays are).
The only difference is that the pointer notation is rather more cryptic.
Code:

```int arr2d[2][4] = { { 0 , 1 , 2 , 3 } , {4, 5 , 6 , 7}} , (*p)[4]; // note that p = arr2d and p = &arr2d[0] are the same thing for ( p = arr2d ; p < arr2d + 2 ; p++ ) { }```
Instead of being "p is a pointer to a struct", you have instead "p is a pointer to an array of 4 int"

Note that this is a very different thing to int *p[4], which is an array of 4 pointers to int.

You can make 2D arrays with both kinds of pointers.
The first is a single block of memory (much like an array of structs would be in contiguous memory).
But each row of an array of pointers would need to be allocated separately. There is even no restriction on each 'row' of the array being the same length.
• 11-02-2012
anduril462
(*p)[4] is not a double pointer declaration, nor is it "cheating". You simply aren't reading/understanding the type of p correctly in your first example. Declared on a line of it's own, it looks like this:
Code:

`int (*p)[4];`
p is a pointer to array of 4 ints. That is different from a pointer to pointer to int. Arrays and pointers are not equivalent. See here: Arrays and Pointers, particularly 6.1-6.4b, and 6.8-6.13. Also, for help reading complex type declarations, I find this link helpful: Arrays and Pointers. There was another good link posted a few weeks back, but I can't find it.

Now, in the first post, since p is a pointer to array of 4 ints, doing p++ increases the address by sizeof(array of 4 ints), or 4*sizeof(int). In the second post, p is a pointer to int, so p++ increments it by sizeof(int), not (#COLUMNS * sizeof(int)).

Print out the relevant sizes of what p points to, ints, array rows, etc to help you understand. For snippet 1:
Code:

```printf("sizeof(int) = %d\n", sizeof(int)); printf("sizeof(*p) (i.e. the size of what p points to) = %d\n", sizeof(*p)); printf("sizeof(arr2d[0]) = %d\n", sizeof(arr2d[0])); for( p = &arr2d[0]; p < &arr2d[2]; p++) {     printf("p = %p (*p)[i] = %d arr2d[0][0] = %d\n" , (*p)[i] , arr2d[0][0] ); }```
Compile and run:
Code:

```sizeof(int) = 4 sizeof(*p) (i.e. the size of what p points to) = 16 sizeof(arr2d[0]) = 16 p = 0xbfb9c9c8 (*p)[i] = 0 arr2d[0][0] = 0 p = 0xbfb9c9d8 (*p)[i] = 4 arr2d[0][0] = 0```
Notice p increments by 16, the size of 4 ints, or one row in a 2-d array with 4 columns per row.

For snippet 2:
Code:

```    printf("sizeof(int) = %d\n", sizeof(int));     for( p = arr2d[0]; p < arr2d[1] + 4 ; p++)     {         printf("p = %p, *p = %d\n" , (void *)p, *p );     }```
Output:
Code:

```sizeof(int) = 4 p = 0xbf991bbc, *p = 0 p = 0xbf991bc0, *p = 1 p = 0xbf991bc4, *p = 2 p = 0xbf991bc8, *p = 3 p = 0xbf991bcc, *p = 4 p = 0xbf991bd0, *p = 5 p = 0xbf991bd4, *p = 6 p = 0xbf991bd8, *p = 7```
Notice that p increments by 4 bytes only, the size of one single int.
• 11-02-2012
Mr.Lnx
Thank you both of you. I know how it works... but I think that I still face some difficulties.

For instance... why the type of a[rows][cols] is different from (*p)[cols] ? they are int both of them.

the first one is an array of arrays of course... the second one is an array of arrays too but the only different is that the
elements have #cols distance among in the second situation with the pointer....
• 11-02-2012
anduril462
Quote:

Originally Posted by Mr.Lnx
For instance... why the type of a[rows][cols] is different from (*p)[cols] ? they are int both of them.

It seems you are not referring to declarations, but how you use them in code, i.e. how you would access an element from your array. arr2d and p are declared with different types, but the expressions arr2d[r][c] and (*p)[c] are of the same type. Why do you think they are different?

EDIT:
Quote:

the first one is an array of arrays of course... the second one is an array of arrays too but the only different is that the
elements have #cols distance among in the second situation with the pointer....
Those variables are not of the same type. The second is most definitely not an array of arrays, it is a pointer to an array. Pointers and arrays are different. They have some similarities, and in some ways they overlap, but they are two different things. Did you read the C-FAQ link I provided in post #3?

EDIT 2:
Now, that doesn't mean that you can't use each of them in different expressions that result in the same type. But the variables themselves are not of the same type.
• 11-03-2012
Mr.Lnx
I was confused because I thought that the type of (*p)[c] is int. I have read the C-FAQ about the pointers and arrays of course... there are differences ... you can't advance the name of an array as a pointer i.e arr2d++ or sizeof(arr2d) != sizeof(p) . In sizeof operator the prototype of C defines that it is not converted to a pointer.

sizeof(int) = 4 bytes. I try to understand how does the pointer go 16 bytes in memory.

The arr2d[c] array is type (*p) ? Due its declaration ? You said that the expressions are of the same type... (int both of them) but not the variables...

so arr2d[c] variable is type of (*p). Right?
• 11-03-2012
Mr.Lnx
I think I get it . p is a pointer to array not simple int. Is a double pointer .. point to array (which is a pointer on its first element) Anyway thank you. :)