Domanda

Ho un file di testo delimitato da tabulazioni che sto analizzando. La sua prima colonna contiene stringhe del formato chrX , dove X indica una serie di stringhe, ad es. & Quot; 1 " ;, " 2 " ;, ..., " X "," "Y".

Questi sono memorizzati ciascuno in un char * chiamato cromosoma , mentre il file viene analizzato.

Il file di testo è ordinato lessicograficamente sulla prima colonna, cioè avrò un numero di righe che iniziano con " chr1 " ;, e quindi " chr2 " ;, ecc.

Ad ogni " chrX " voce, devo aprire un altro file associato a questa voce:

FILE *merbaseIn;

// loop through rows...

if (chromosome == NULL)                                                                                                                                                   
    openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN);                                                                                                      
else {                                                                                                                                                                    
    if (strcmp(chromosome, fieldArray[i]) != 0) { // new chromosome                                                                                                   
        fclose(merbaseIn); // close old chromosome FILE ptr                                                                                                                                                                                                                                    
        free(chromosome); // free old chromosome ptr                                                                                                                          
        openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN); // set up new chromosome FILE ptr                                                                  
    }                                                                                                                                                                       
}  
// parse row

Ho la funzione openSourceFile che è definita come segue:

void openSourceFile (char** chrome, const char* field, FILE** filePtr, const char *path) {
    char filename[100];                                                                                                                                                           
    *chrome = (char *) malloc ((size_t) strlen(field));
    if (*chrome == NULL) {                                                                                                                                                        
        fprintf(stderr, "ERROR: Cannot allocate memory for chromosome name!");                                                                                                      
        exit(EXIT_FAILURE);                                                                                                                                                         
    }                                                                                                                                                                             

    strcpy(*chrome, field);                                                                                                                                                       
    sprintf(filename,"%s%s.fa", path, field);                                                                                                                                     

    *filePtr = fopen(filename, "r");                                                                                                                                              
    if (*filePtr == NULL) {                                                                                                                                                       
        fprintf(stderr, "ERROR: Could not open fasta source file %s\n", filename);                                                                                                  
        exit(EXIT_FAILURE);                                                                                                                                                         
    }                                                                                                                                                                             
}      

Il problema è che la mia applicazione si chiude con un errore di segmentazione che va dal primo cromosoma al secondo (da chr1 a chr2 ) nella riga seguente, dove chiudo il primo file cromosomico che ho aperto:

fclose(merbaseIn);

So che non sto passando a fclose un puntatore NULL, perché fino all'errore di segmentazione, sto leggendo i dati da questo file. Posso anche avvolgerlo in un condizionale e ottengo ancora l'errore:

if (merbaseIn != NULL) {
    fclose(merbaseIn);
}

Inoltre, so che openSourceFile funziona (almeno per chr1 , quando si configura il primo handle di file di FILE * ) perché la mia applicazione analizza le righe chr1 e legge correttamente i dati dal file sorgente FILE * .

Che cos'è questa chiamata fclose che sta causando un errore di segmentazione?

È stato utile?

Soluzione

valgrind --db-attach=yes --leak-check=yes --tool=memcheck --num-callers=16 --leak-resolution=high ./yourprogram args

È molto probabile che il segfault sia causato dalla corruzione della memoria nell'heap, non da qualsiasi cosa colpisca la gente del posto. Valgrind ti mostrerà immediatamente il primo accesso sbagliato che hai effettuato.

Modifica: l'opzione --db-attach su valgrind è stata deprecata dalla versione 3.10.0 nel 2014. Le note sulla versione indicano:

The built-in GDB server capabilities are superior and should be used
instead. Learn more here:

http://valgrind.org /docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

Altri suggerimenti

un errore che noto è questa riga:

 *chrome = (char *) malloc ((size_t) strlen(field));

che dovrebbe essere:

 *chrome = (char *) malloc ((size_t) strlen(field)+1);

Questo perché una stringa ha uno 0 di chiusura alla fine del quale devi anche fare spazio

La migliore ipotesi è che un'altra parte del codice stia danneggiando la memoria attraverso un sovraccarico del buffer o un bug simile.

Sebbene sia improbabile che sia la causa, hai una potenziale condizione di superamento nell'array del nome file quando il nome file completo supera i 100 caratteri.

Suggerirei di utilizzare un debugger per controllare le modifiche nella posizione della memoria utilizzata dalla variabile merbaseIn.

Problema puntatore generico

C è un linguaggio eccezionale ma richiede di non ostruire la tua memoria. Oltre al problema precedentemente notato in cui il malloc è corto di 1 byte, potresti avere altri problemi con il puntatore.

Suggerirei utilizzando un debugger di memoria . In passato, Electric Fence era piuttosto popolare, ma oggigiorno leggi di più su valgrind . Ci sono molte altre scelte.

Oltre all'errore riscontrato da reinier , sospetto che:

free(chromosome);

dovrebbe essere seguito da:

chromosome = NULL;

al fine di prevenire il potenziale utilizzo di un valore non più valido.

perché questo filePtr FILE ** se solo questo filePtr FILE * fosse sufficiente? solo un pensiero ...

valgrind con memcheck è sicuramente lo strumento giusto per scoprire la causa dell'errore di segmentazione. Per usare un debugger con valgrind , nota che l'opzione --db-attach su valgrind è stata deprecata da quando Valgrind 3.10.0 è stato rilasciato in 2014. Le note di rilascio indicano:

The built-in GDB server capabilities are superior and should be used
instead. Learn more here:

http://valgrind.org /docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

Esamina tutti i luoghi che hai utilizzato " malloc " e verifica se hai commesso un errore.

Ad esempio, stavo inserendo righe lette da un file in un carattere **, ma in modo errato lo ha ingannato come:

my_list = malloc(sizeof(char) * num_lines_found_in_file);

Quando avrebbe dovuto essere:

my_list = malloc(sizeof(char*)* num_lines_found_in_file);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top