Comunque effettua due allocazioni di matrice ma alla fine non le dealloca è questo è un errore a prescindere dal resto.
Comunque la AllocateMemory è sostanzialmente corretta in quanto sfrutta un array come matrice giocando con l'offset degli indici, invece di ricorrere al classico doppio puntatore con annesso ciclo.
In casi simili la cella della matrice m[i][j] si ottiene come:
MAX_COL * i + j
dove MAX_COL è il numero di colonne massimo di cui è composta la matrice.
L'inconveniente (credo unico) è che non si può accedere a tale cella come m[i][j], ma devi scrivere m[MAX_COL * i + j] ogni volta.
Se i primi dati che leggi con fscanf sono: 6,4,3; quel 3 della AllocateMemory potrebbe essere un refuso di una implementazione precedente. Nota che la riga successiva infatti ha uno 0 come riga e non esistono matrici con 0 righe.Pensandoci bene però quel "AllocateMemory(3, r*c)", in particolare il "3" non so come possa servire in termini di allocazione di memoria :|