Question

J'ai un fichier texte délimité par des tabulations que je suis en train d'analyser. Sa première colonne contient des chaînes au format chrX , où X désigne un ensemble de chaînes, par exemple, "1", "2", ..., ",". X "," Y ".

Ils sont chacun stockés dans un char * appelé chromosome , lors de l'analyse du fichier.

Le fichier texte est trié sur la première colonne lexicographiquement, c’est-à-dire que je vais avoir un nombre de lignes commençant par "chr1", puis "chr2", etc.

.

A chaque "chrX" entrée, je dois ouvrir un autre fichier associé à cette entrée:

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

J'ai la fonction openSourceFile définie comme suit:

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

Le problème est que mon application se ferme avec une erreur de segmentation allant du premier chromosome au deuxième (de chr1 à chr2 ) à la ligne suivante, où je ferme le premier fichier chromosome que j'ai ouvert:

fclose(merbaseIn);

Je sais que je ne passe pas à fclose un pointeur NULL, car jusqu'à la défaillance de segmentation, je lis les données de ce fichier. Je peux même envelopper ceci dans une condition et je reçois toujours le défaut:

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

De plus, je sais que openSourceFile fonctionne (au moins pour chr1 , lors de la configuration du premier descripteur de fichier de FILE * ) car mon application analyse les lignes chr1 et lit correctement les données du fichier source FILE * .

En quoi cet appel fclose est-il à l’origine d’une erreur de segmentation?

Était-ce utile?

La solution

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

Il est très probable que le segfault soit causé par une corruption de mémoire sur le tas, mais pas par tout ce qui touche les locaux. Valgrind vous montrera immédiatement le premier accès erroné que vous avez effectué.

Edition: L'option - db-attach de valgrind est obsolète depuis la version 3.10.0 en 2014. Les notes de publication indiquent:

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

Autres conseils

une erreur que je remarque est cette ligne:

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

qui devrait être:

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

C’est parce qu’une chaîne a un 0 de clôture à la fin que vous devez également faire de la place pour

La meilleure hypothèse est qu'une autre partie de votre code est en train de corrompre la mémoire par un dépassement de tampon ou un bogue similaire.

Bien qu'il soit peu probable que cela soit la cause du problème, votre tableau de noms de fichiers présente un risque de saturation lorsque le nom de fichier complet dépasse 100 caractères.

Je suggérerais d'utiliser un débogueur pour surveiller les modifications apportées à l'emplacement de la mémoire utilisé par la variable merbaseIn.

Problème générique avec le pointeur

C est un bon langage, mais il vous est demandé de ne pas graver votre propre mémoire. En plus du problème précédemment noté où le malloc est court d’un octet, vous pouvez avoir d’autres problèmes de pointeur.

Je suggérerais d'utiliser un débogueur de mémoire . Auparavant, la clôture électrique était plutôt populaire, mais de nos jours, en savoir plus sur valgrind . Il y a beaucoup d'autres choix.

Outre l'erreur trouvée par reinier , je soupçonne que:

free(chromosome);

devrait être suivi de:

chromosome = NULL;

afin d'éviter l'utilisation potentielle d'une valeur qui n'est plus valide.

pourquoi ce FILE ** filePtr si seulement ce FILE * filePtr suffisait? juste une pensée ...

valgrind avec memcheck est certainement le bon outil pour découvrir la cause de l’erreur de segmentation. Pour utiliser un débogueur avec valgrind , notez que l'option - db-attach de valgrind est obsolète depuis la publication de Valgrind 3.10.0. 2014. Les notes de publication indiquent:

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

Passez en revue chaque lieu où vous avez utilisé "malloc" et voyez si vous avez commis une erreur.

Par exemple, je mettais des lignes lues dans un fichier dans un caractère **, mais je me suis trompé malloced comme:

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

Quand cela aurait dû être:

my_list = malloc(sizeof(char*)* num_lines_found_in_file);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top