views:

75

answers:

4

I saw this example when I was trying to figure out how to pass pointers to dynamically allocated 2d arrays to functions:

void zeroit(int **array, int nrows, int ncolumns)
 {
 int i, j;
 for(i = 0; i < nrows; i++)
  {
  for(j = 0; j < ncolumns; j++)
   array[i][j] = 0;
  }
 }

I tried it and it works, but I don't understand how. How does the function "zeroit" calculates the correct address?

+1  A: 

Here you are:
http://www.eskimo.com/~scs/cclass/int/sx9a.html
http://www.eskimo.com/~scs/cclass/int/sx9b.html

Frozen Spider
Only the second link is relevant really to the question, but +1 for beating me by linking rather than DIY diagrams that i was doing
tobyodavies
I see it now, it doesn't have to know by the nature of dynamic arrays. Thanks!
yam
A: 

No calculation is needed. Your function "zeroit" reaches an integer through "double indirection".

"int **array" is not really a matrix of integers. It is exactly a "pointer on pointers on integer" - more a vector of, vectors of integers. When accessing "array[i]" (first indirection), you get an "int *", ie the address of the ith vector of integers. When accessing "array[i][j]" (second indirection), you get an "int", ie the jth integer of the ith vector.

Noe
A: 

If your "2d array" is really just an array of pointers to individual rows, then it computes the correct address merely by looking up the address of the row then applying an offset to it. However, this is a very inefficient way to implement a "2d array". The best way is to simply use normal 1-dimensional arrays and compute the index yourself with multiplication and addition, but in C99 you can also use vla semantics to have the compiler treat it like a real 2d array.

R..
A: 

if you consider the memory layout/addresses below:

array     =  |10|11|12|

array[0]  =  |20|21|22|

array[1]  =  |30|31|32|

cell 10 contains a pointer to cell 20, and cell 11 contains a pointer to 30, this is called double indirection - array is a sequential, word width sequence of pointers to arrays of ints, there is no need to calculate, just dereference two pointers

tobyodavies