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

int main() 
{
  int n, m, p, nmp, nm, i, j, k;
  double *ttt;
  double **tt;
  double ***t;

  /* Input dimensions of tensor */
  printf("\nPlease input dimensions of tensor: n, m, p ?? ");
  scanf("%d %d %d", &n, &m, &p);

  /* Check that n, m, p are positive integers */
  if ((n <= 0) || (m <= 0) || (p <= 0)) 
   {
    printf("\nError: invalid values for n and/or m and/or p\n");
    exit(1);
   }  

  /* Allocate memory for n x m x p tensor of doubles */
  nmp = n * m * p;
  ttt = (double *) malloc(nmp * sizeof(double));

  /* Allocate memory for n x m x 1 matrix of pointers to doubles */
  nm = n * m;
  tt = (double **) malloc(nm * sizeof(double *));

  /* Allocate memory for n x 1 x 1 vector of pointers to pointers to doubles */
  t = (double ***) malloc(n * sizeof(double **));

  /* Set pointers in vector t to point to beginning of rows in matrix tt 
     Set pointers in matrix tt to point to beginning of rows 
      in tensor ttt */
  for (i = 0; i < n; i++)
    {
      t[i] = tt + m*i;

      for (j = 0; j < m; j++)
        {
          t[i][j] = ttt + m*p*i + p*j;
        }
    } 

  /* Output addresses of elements of tensor */
  printf("\n");
  for (i = 0; i < n; i++)
    {
      for (j = 0; j < n; j++)
        {
          for (k = 0; k < n; k++)
            {
              printf("i = %3d  j = %3d  k = %3d  &t[i][j][k] = %X\n", 
               i, j, k, &t[i][j][k]);
            }
        }
    }

  /* Free memory */
  free(t);
  free(tt);
  free(ttt);

  return 0;
}
