If it's just about minimising the number of calls to memory allocation functions you can created such a jagged array like this:
#include <stdlib.h>
#include <stdio.h>
int ** alloc_jagged_2d_array_of_int(size_t n, size_t m)
{
  int ** result = NULL;
  size_t t = 0;
  t += n * sizeof *result;
  t += n*m * sizeof **result;
  result = calloc(1, t);
  if (NULL != result)
  {
    for (size_t i = 0; i < n; ++i)
    {
      result[i] = ((int*) (result + n)) + i*m;
    }
  }
  return result;
}
Use it like this:
#include <stdlib.h>
#include <stdio.h>
int ** alloc_jagged_2d_array_of_int(size_t, size_t);
int main(void)
{
  int result = EXIT_SUCCESS;
  int ** p = alloc_jagged_2d_array_of_int(2, 3);
  if (NULL == p)
  {
    perror("alloc_jagged_2d_array_of_int() failed");
    result = EXIT_FAILURE;
  }
  else
  {
    for (size_t i = 0; i < 2; ++i)
    {
      for (size_t j = 0; j < 3; ++j)
      {
        p[i][j] = (int) (i*j);
      }
    }
  }
  /* Clean up. */
  free(p);
  return result;
}