add to source, compile and run. very brief example usage (basically just the calling syntax) included in the commentstwo functions; the first dynamically allocates a 2D array with a user- or program-specified number of rows/columns; the second deallocates the same array. demonstrates the mutlti-dimensional usage of malloc and free.

/*   allocate2D
/*   function to dynamically allocate 2-dimensional array using malloc.
/*
/*   accepts an int** as the "array" to be allocated, and the number of rows and
/*   columns.
*/
void allocate2D(int** array, int nrows, int ncols) {

     /*  allocate array of pointers  */
     array = ( int** )malloc( nrows*sizeof( int* ) );

     /*  allocate each row  */
     int i;
     for(i = 0; i < nrows; i++) {
          array[i] = ( int* )malloc( ncols*sizeof( int ) );
     }

}

/*   deallocate2D[Click Here](null)
/*   corresponding function to dynamically deallocate 2-dimensional array using 
/*   malloc.
/*
/*   accepts an int** as the "array" to be allocated, and the number of rows.  
/*   as with all dynamic memory allocation, failure to free malloc'ed memory
/*   will result in memory leaks
*/
void deallocate2D(int** array, int nrows) {

     /*  deallocate each row  */
     int i;
     for(i = 0; i < nrows; i++) {
          free(array[i]);
     }

     /*  deallocate array of pointers  */
     free(array);

}

/*   EXAMPLE USAGE:    
int** array1;

allocate2D(array1,1000,1000); //allocates a 1000x1000 array of ints

deallocate2D(array1,1000);    //deallocates the same array
*/