Since the dimensions are not known the compiler cannot generate appropriate address arithmetic for a two dimensional array at compile time. A pointer into a block of memory can't be used to offset into the nth row, if you don't know how long each row is. However, the compiler can generate address arithmetic for a one dimensional array. All it needs is the size of the elements. For integers for instance that would be 4 bytes (in most circumstances today), so given a pointer, the nth element is n*4 bytes from the beginning.

So, the way to get a two dimensional array, is to organize it based on an array of pointers. Declare:

int **matrix;

Now allocate the "row pointers" (assume the variable x contains the number you need):

matrix=(int **)calloc(x,sizeof(int *));

Now allocate space for each row:

for(i=0; i<x; ++i)matrix[i]=(int *)calloc(y,sizeof(int));

Now you have a variable named matrix, which points to an array of pointers. Each element in the array points to an array of integers. And you get to use it with the familiar syntax:

a=matrix[i][j];

The "invisible" difference is that a double dereference is taking place. Instead of address calculating its way into a block of memory, it follows the pointer from matrix to an array of integer pointers. Finds the right row, the follows that pointer to an array of integers and finds the right element.

So, the way to get a two dimensional array, is to organize it based on an array of pointers. Declare:

int **matrix;

Now allocate the "row pointers" (assume the variable x contains the number you need):

matrix=(int **)calloc(x,sizeof(int *));

Now allocate space for each row:

for(i=0; i<x; ++i)matrix[i]=(int *)calloc(y,sizeof(int));

Now you have a variable named matrix, which points to an array of pointers. Each element in the array points to an array of integers. And you get to use it with the familiar syntax:

a=matrix[i][j];

The "invisible" difference is that a double dereference is taking place. Instead of address calculating its way into a block of memory, it follows the pointer from matrix to an array of integer pointers. Finds the right row, the follows that pointer to an array of integers and finds the right element.