Game Development Community

Why doesn't int** equal to int[][]???

by Berserk · in Technical Issues · 10/16/2006 (9:10 am) · 13 replies

.

#1
10/16/2006 (10:24 am)
What line are you getting the error on?

int** ar2ptr = &&array2;

this doesnt look right to me. did you try using just one ampersand?
#2
10/16/2006 (10:44 am)
.
#3
10/16/2006 (11:50 am)
The difference between an int** and an int[][] is that one of them has size information.
int foo[2][2];
int **bar = (int **)foo;
Should work just fine

In your code
int** ar2ptr = (int**)array2;
#4
10/16/2006 (1:07 pm)
Remember that you have created to different kinds of arrays: one is an array of pointers to rows of memory that you allocated with new(). The other is an array of memory on the stack which holds all the rows of data contiguously. Those are very different things and need different methods to access.

This illustrates the different access methods:

void printArray(int **nomeArray) {
   for(int y = 0; y < 2; y++) {
      for(int x = 0; x < 4; x++) {
         printf("%d", nomeArray[x][y]);
      }        printf("\n");
   }
}
void initArray(int **nomeArray) {
   for(int y = 0; y < 2; y++) {
      for(int x = 0; x < 4; x++) {
         nomeArray[x][y] = x+y;
      }
   }
}
void printArray2(int nomeArray[][2]) {
   for(int y = 0; y < 2; y++) {
      for(int x = 0; x < 4; x++) {
         printf("%d", nomeArray[x][y]);
      }        printf("\n");
   }
}
void initArray2(int nomeArray[][2]) {
   for(int y = 0; y < 2; y++) {
      for(int x = 0; x < 4; x++) {
         nomeArray[x][y] = x+y;
      }
   }
}

int main(void) {
   int** array = new int*[4];
   for(int a = 0; a < 4; a++)
      array[a] = new int[2];
   int array2[4][2] = {0, 0, 0, 0, 0, 0, 0, 0};
   initArray(array);
   printArray(array);
   initArray2(array2);
   printArray2(array2);
   return 0;
}
#5
10/17/2006 (3:10 am)
.
#6
10/17/2006 (3:16 am)
.
#7
10/17/2006 (5:29 am)
Quote:
By the way, as far as I know, however you define an array of array it still is
a pointer to a pointer array, in wich every pointer element points to an array.

No, that's the key point. when you do this
int** array = new int*[4];
   for(int a = 0; a < 4; a++)
      array[a] = new int[2];
you have told the compiler to create code to allocate an array of pointers from the heap. then you told it to allocate four more arrays of ints and stored their pointers in the first array.

But that's different than
int array2[4][2] = {0, 0, 0, 0, 0, 0, 0, 0};
where you told the compiler to allocate space on the stack for an array of eight integers. Until you reference it, there are no pointers involved in that.

Quote:
As well as a unidimensional array, however is defined, is a pointer to an array.
Isn't it?
That's true but in the first case the pointer points to some more pointers you created (which then point to the data) and in the second case the pointer points to the data.

Another variation might illuminate it even more. Suppose you did this
int* array[4];
   for(int a = 0; a < 4; a++)
      array[a] = new int[2];
Now you would have space for four pointers on the stack initialized to point to 4 arrays in the heap.
#8
10/18/2006 (2:52 am)
.
#9
10/18/2006 (5:17 am)
You can reference it either way. In both cases, a reference pointer is passed to the method. but the method needs to know how to derefence the pointer. Notice that the body of the two styles of code in my example is the same, only the reference parameter style is different. In the first case it is **nomeArray and in the second it is nomeArray[][2]. That's enough for the compiler to know about the layout of the memory pointed to by the reference. In the first case it derefences by *(*(nomeArray+x)+y) and in the second it produces code that dereferences by *(nomeArray+2x+y).

Hope that helps.

Tim
#10
10/18/2006 (7:41 am)
.
#11
10/18/2006 (7:55 am)
Yes 2*x. If you think of the x as counting the rows and y as counting the columns, then address has to move 2 integers, the width of a row, for each row, which is counted by x.

The compiler does this for you when it sees that the argument is described as [][2] array. In other words, that's not code you have to write, but you could...

If you did, your routine might look like this:
int array2[4][2] = {0, 0, 0, 0, 0, 0, 0, 0};

void printArray2(int *array2) {
   for(int y = 0; y < 2; y++) {
      for(int x = 0; x < 4; x++) {
         printf("%d", *(array2+2*x+y);
      }
        printf("\n");
   }
}

Notice there that I only described the array reference as a pointer to a linear array of integers.

Edit: To clarify the source array.
#12
10/18/2006 (12:56 pm)
.
#13
10/18/2006 (1:07 pm)
Lol, your very welcome.

I remember many years ago when I first understood pointers. It was like discovering the Holy Grail of C. But then comes all that other stuff and you feel dumb again anyway.

Good Luck.

Tim