#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

int main(void)
{
 int **rptr;
 int *aptr;
 int *testptr;
 int k;
 int nrows = 5;     /* Both nrows and ncols could be evaluated */
 int ncols = 10;    /* or read in at run time */
 int row, col;
    /* we now allocate the memory for the array */
 aptr = malloc(nrows * ncols * sizeof(int *));
 if(aptr == NULL)
 {
   puts("\nFailure to allocate room for the array");
   exit(0);
 }
    /* next we allocate room for the pointers to the rows */
 rptr = malloc(nrows * sizeof(int *));
 if(rptr == NULL)
 {
   puts("\nFailure to allocate room for pointers");
   exit(0);
 }
    /* and now we 'point' the pointers */
 clrscr();
 for(k = 0; k < nrows; k++)
 {
    rptr[k] = aptr + (k * ncols);
 }
 printf("\n\n\nIndex   Pointer(hex)   Pointer(dec)   Diff.(dec)");

 for(row = 0; row < nrows; row++)
 {
   printf("\n%d         %p         %d", row, rptr[row], rptr[row]);
   if(row > 0)
     printf("              %d",(int)(rptr[row] - rptr[row-1]));
 }
 for(row = 0; row < nrows; row++)
 {
    for(col = 0; col < ncols; col++)
    {
      rptr[row][col] = row + col;
      printf("%d ", rptr[row][col]);
    }
    putchar('\n');
 }
 puts("\n\n\n");

    /* and here we illustrate that we are, in fact, dealing with
       a 2 dimensional array in a _contiguous_ block of memory. */

 testptr = aptr;
 for(row = 0; row < nrows; row++)
 {
   for(col = 0; col < ncols; col++)
   {
     printf("%d ", *(testptr++));
   }
   putchar('\n');
 }
 return 0;
}