Sto implementando l'algoritmo del simplesso duale per un esame universitario, e per inizializzare il problema leggo un file .dat con tutti i dati tramite fscanf(). Tra questi sono presenti anche il numero di vincoli (che indico con "m") e delle variabili (che indico "n").

Per inizializzare la matrice mxn chiamo la funzione malloc() per allocare lo spazio richiesto.
Dopo aver inizializzato gli elementi della matrice, l'algoritmo richiede eventualmente (non sto a spiegarvi il motivo visto che non è inerente al problema) di aggiungere ulteriori righe e colonne. Per farlo chiamo la funzione realloc() (dopo aver aumentato m ed n del numero di righe e di colonne rispettivamente richiesti).
A questo punto provo a inizializzare i nuovi elementi inseriti, ma all'ultima riga (i = m) mi dà segmentation fault. Ho debuggato per un'ora e sono sicuro al 100% che l'errore proviene dal realloc(), ma non capisco perchè. Probabilmente sto gestendo male i puntatori. Vi incollo il codice:

codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Costanti
#define MAX_FILENAME_LENGTH 30  // Lunghezza massima nome del file
#define M 1000000000  // Valore di M (per il vincolo artificiale)
#define PRECISIONE 0.0000001  // Precisione per diminuire gli errori nei confronti

// Prototipi funzioni
int read_file_and_init(const char *filename, double **Mat, int *m, int *n, int **Segni);

// Funzione main()
int main()
{
    // Variabili locali
    double **Mat;  // Tableau del problema
    int **Segni;  // Segno dei vincoli
    long **Stato;  // Stato delle variabili
    long **Base;  // Variabili in base
    int m, n;  // Numero di condizioni e di variabili
    char filename[MAX_FILENAME_LENGTH];  // Nome del file di input
    int found = 0;  // Verrà settata a 1 se il file di input esiste
    int num_slack = 0;  // Numero di variabili slack
    int va = 0;  // "Booleano" per sapere se dobbiamo inserire il vincolo artificiale
    int i, j;  // Per cicli

    // Mostriamo questo messaggio
    printf("Questa applicazione permette di applicare il metodo del Simplesso Duale alle istanze passate in input.\n");

    // Cicliamo finchè non troviamo il file di input
    do {

        // Chiediamo all'utente il nome del file
        printf("\nInserisci il nome del file di input: ");
        scanf("%s", filename);

        // Controlliamo la lunghezza del nome del file
        if(strlen(filename) > MAX_FILENAME_LENGTH)
        {
            printf("Il nome del file supera la lunghezza massima consentita!\n");
            continue;
        }

        // Tentiamo di aprire il file
        found = read_file_and_init(filename, &Mat, &m, &n, &Segni);

        if(!found) printf("File non trovato!\n");

    } while(!found);


    // Contiamo il numero di variabili slack da aggiungere
    for (i = 1; i <= m; ++i)
	{
		if(Segni[i] == 1 || Segni[i] == -1) ++num_slack;
	}

	// Controlliamo se dobbiamo aggiungere il vincolo artificiale
    for (j = 1; j <= n; ++j)
	{
		if(Mat[0][j] > 0)  // Se troviamo un zj - cj > 0,  allora dobbiamo aggiungere il vincolo
		{
		    ++num_slack;
		    va = 1;
		    break;
		}
	}

	// Memorizziamo le nuove dimensioni del tableau
	if(va) ++m;
	n += num_slack;

	// Inizializziamo il resto del tableau se abbiamo trasformato in forma standard e/o aggiunto il v.a.
	if(va || num_slack > 0)
	{
	    // Allochiamo un nuovo blocco di memoria
        Mat = realloc(Mat, (m+1) * sizeof(double*));
        for (i = 0; i <= m; ++i) Mat[i] = realloc(Mat[i], (n+1) * sizeof(double*));

        // Azzeriamo i nuovi coefficienti
        for(i = 1; i <= m; ++i)
        {
            for(j = 1; j <= n; ++j)
            {
                if(i == m || j > (n - num_slack))
                {
                    Quando assegna Mat[m][j] = 0.0 dà segfault
                    Mat[i][j] = 0.0;  // Azzeriamo solo la riga del v.a. e/o le colonne delle variabili slack
                }
            }
        }
	}

    system("pause");

    return 0;
}

// Funzione che preleva l'input dai file e inizializza il problema
int read_file_and_init(const char *filename, double **Mat, int *m, int *n, int **Segni)
{
    // Variabili locali
	FILE *fdata;  // Stream di lettura
	int i, j, k;  // Per cicli
	double **tmpMat, **tmpSegni;  // Tableau e versi temporanei
	double cc;  // Variabile costi
	long no;  // Numero di coefficienti non-zero della j-esima colonna
	long rr;  // Indice di riga del corrente coefficiente non-zero

	// Apriamo il file di input in lettura
	fdata = fopen(filename, "r");

	// Controlliamo che il file esista, in caso contrario ritorniamo
	if(fdata == NULL) return 0;

	// Leggiamo il numero di righe e di colonne
	fscanf(fdata,"%d %d", n, m);

	// Allochiamo il tableau con le relative dimensioni
    tmpMat = (double*) malloc((*m+1) * sizeof(double*));
    for (i = 0; i <= (*m); ++i) tmpMat[i] = (double*) malloc((*n+1) * sizeof(double));

    // Allochiamo l'array dei versi
    tmpSegni = (double*) malloc((*m) * sizeof(double*));

	// Inizializziamo il tableau
	for(i = 0; i <= (*m); ++i)
	{
        for(j = 0; j <= (*n); ++j)
        {
            tmpMat[i][j] = 0.0;
        }
	}

	// Leggiamo il vettore dei termini noti
	for(i = 1; i <= (*m); ++i)
	{
		fscanf(fdata, "%lf", &(tmpMat[i][0]));
	}

	// Leggiamo il vettore dei versi delle condizioni
	for (i = 1; i <= (*m); ++i)
	{
		fscanf(fdata, "%d", &(tmpSegni[i]));
	}

	// Leggiamo la matrice dei coefficienti
	for (j = 1; j <= (*n); ++j)
	{
		// Leggiamo il costo della j-esima colonna
		fscanf(fdata, "%lf", &cc);
		tmpMat[0][j] = -cc;

		// Leggiamo il numero di coefficienti non-zero della j-esima colonna
		fscanf(fdata, "%d", &no);

		// Leggiamo i coefficienti non-zero della j-esima colonna
		for (k = 1; k <= no; ++k)
		{
			fscanf(fdata, "%d", &rr);  // Reperiamo l'indice di riga
			fscanf(fdata, "%lf", &(tmpMat[rr][j]));  // Memorizziamo il coefficiente
		}
	}

	// Chiudiamo il file
	fclose(fdata);

	// Memorizziamo nelle variabili originali
    *Mat = tmpMat;
    *Segni = tmpSegni;

	// Ritorniamo
	return 1;
}