Una matrice altro non è che una lista di liste. In C questo si traduce in un puntatore a puntore ad int, la cui prima dimensione è rapprsentata da puntatori ad int. Una cosa del genere, assumendo N = 5.

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

int main(int argc, char **argv){

int i, j, n = 5, **matrix;

if(!(matrix = (int **)malloc(n*sizeof(int *))))
abort();

for(i = 0; i < n; i++){
*(matrix+i) = (int *)malloc(n*sizeof(int));
for(j = 0; j < n; j++)
*((*(matrix+i))+j) = rand()%100;
}

for(i = 0; i < n; i++){
for(j = 0; j < n; j++)
printf("%d\t", *((*(matrix+i))+j));
printf("\n");
}


SE non sai a priori la dimensione di N, allora dovresti, nel caso, allocare una nuova matrice di dimensione N+1 e copiarvi dentro i dati, con una funzione ad hoc.

Due alternative:

1. Array fornito dalla libreria glib.
2. Una linked list di linked lists (non devi piu preoccuparti di reallocare, ma perdi la possiblità di acceder agli elementi con [][], a meno che tu non ti crei una funzione ad hoc che lo faccia).