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; }

Rispondi quotando