Armazene a matriz triangular com eficiência

Preciso armazenar com eficiência uma matriz triangular inferior, não armazenando todos os zeros na memória, por isso pensei dessa maneira: primeiro aloco memória para cada linha, depois para cada linha aloco i + 1 bytes, para nunca precisa se preocupar com os zeros, mas algo está errado na primeira alocação. O que estou fazendo errado? Este é o meu código, e o compilador sai do programa na linha 8, logo após ler a dimensão da matriz.

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

int main ()
{
  int i, j, **mat1, dim;

  scanf("%d",&dim);
  *mat1 = (int**)calloc(dim, sizeof(int*));

  for(i = 0; i<dim; i++)
    mat1[i] = (int*)calloc(i+1, sizeof(int));

  for(i = 0; i < dim; i++)
    for(j = 0; j < i+1; j++)
       scanf("%d", &mat1[i][j]);

  for(i=0; i<dim; i++)
    for(j=0; j<(i+1); j++)
       printf("%d%c", mat1[i][j], j != (dim-1) ? ' ' : '\n');

  return 0;
}

EDITAR

ok então depois de modificar o código da maneira que você me ajudou, eu tenho que ler uma matriz triangular superior e uma triangular inferior e mostrar seu produto. O problema é que eu não armazeno os zeros na memória, então se eu usar o algoritmo tradicional de 3 para, ele mostrará alguns valores de lixo eletrônico. E se eu inicializar o restante de cada uma das matrizes com 0, é inútil alocar a memória dinamicamente, porque eu também teria os zeros armazenados, então não fiz nada para melhorar a eficiência do armazenamento.Eu acho que tenho que modificar o código em algum lugar, ou talvez os intervalos, mas mesmo assim eu modifico o programa ainda gera (para matriz 3x3) 2 valores de lixo eletrônico no canto superior direito.Como eu poderia fazer isso?

#include <stdio.h>
#include <stdlib.h>
int main ()
{
int i,j,k,**mat1,**mat2,**prod,dim;


printf("Give dimension: \n");
scanf("%d",&dim);

mat1 = (int**)calloc(dim,sizeof(int*));

for(i=0; i<dim; i++)
    mat1[i] = (int*)calloc(i+1,sizeof(int));

mat2 = (int**)calloc(dim,sizeof(int*));

for(i=dim-1; i>-1; i--)
    mat2[i]=(int*)calloc(i+1,sizeof(int));

prod = (int**)calloc(dim,sizeof(int*));
for(i=0; i<dim; i++)
    prod[i] = (int*)calloc(dim,sizeof(int));

printf("Give lower triangular matrix(non 0 values only): \n");
for(i=0; i<dim; i++)
    for(j=0; j<i+1; j++)
        scanf("%d",&mat1[i][j]);

printf("Give upper triangular matrix(non 0 values): \n");
for(i=0; i<dim; i++)
    for(j=i; j<dim;j++)
        scanf("%d",&mat2[i][j]);

printf("Matrix A is: \n");
for(i=0; i<dim; i++)
    for(j=0; j<dim; j++)
        printf("%d%c",j<=i?mat1[i][j]:0,j!=dim-1?' ':'\n');

printf("Matrix B is: \n");
for(i=0; i<dim; i++)
    for(j=0; j<dim; j++)
        printf("%d%c",j>=i?mat2[i][j]:0,j!=dim-1?' ':'\n');

for(i=0; i<dim; i++)
    for(j=0; j<dim; j++)
        for(k=0; k<dim; k++)
            prod[i][j]+=mat1[i][k]*mat2[k][j];


printf("The product of the two matrix is: \n");
for(i=0; i<dim; i++)
    for(j=0; j<dim; j++)
        printf("%d%c",prod[i][j],j!=dim-1?' ':'\n');


return 0;

}

questionAnswers(3)

yourAnswerToTheQuestion