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

double **mat(int M, int N)
{
  int i;
  double **m;

#if 0
  m = (double **)malloc(sizeof(double *)*M);
#if defined(UNSAFE)
  for (i=0; i<M; i++)
    m[i] = (double *)malloc(sizeof(double)*N);
#else
  if (!m)
    return NULL;
  for (i=0; i<M; i++) {
    m[i] = (double *)malloc(sizeof(double)*N);
    if (!m[i]) {
      do free(m[--i]); while (i != 0);
      free(m);
      return NULL;
    }
  }
#endif
#else
  m = (double **)malloc(sizeof(double *)*M);
#if defined(UNSAFE)
  m[0] = (double *)malloc(sizeof(double)*M*N);
#else
  if (!m)
    return NULL;
  m[0] = (double *)malloc(sizeof(double)*M*N);
  if (!m[0]) {
    free(m);
    return NULL;
  }
#endif
  for (i=1; i<M; i++) {
    m[i] = m[i-1] + N;
  }
#endif
  return m;
}
void free_mat(int M, double **m)
{
#if 0
  int i;

  for (i=0; i<M; i++)
    free(m[i]);
#else
  free(m[0]);
#endif
  free(m);
}
void unit_mat(int M, int N, double **m)
{
  int i, j;

  for (i=0; i<M; i++)
    for (j=0; j<N; j++)
      m[i][j] = (i==j) ? 1 : 0;
}
/*
  a[M][N], b[M][L], c[M][N]: matrix
 */
void mat_mult_mat(int M, int N, int L, double **a, double **b, double **c)
{
  int i, j, k;

  for (i=0; i<M; i++)
    for (j=0; j<L; j++)
      for (c[i][j] = 0, k=0; k<N; k++)
        c[i][j] += a[i][k]*b[k][j];
}

int main(int argc, char *argv[])
{
  int i, j, n = 3;
  double **a;
  double **b;
  double **c;

  if (argc == 1+1) {
    n = atoi(argv[1]);
    if (n < 0) return 1;
  }
  a = mat(n, n);
  b = mat(n, n);
  c = mat(n, n);
#if defined(UNSAFE)
#else
  if (!a || !b || !c) { fprintf(stderr, "malloc failed\n"); return 1; }
#endif
  unit_mat(n, n, a);
  unit_mat(n, n, b);
  mat_mult_mat(n, n, n, a, b, c);
  for (i=0; i<n; i++) {
    for (j=0; j<n; j++)
      printf("%g ", c[i][j]);
    printf("\n");
  }
  return 0;
}
