Pergunta

Eu tenho um arquivo de texto delimitado por guia que eu estou analisando. A primeira coluna contém cordas da chrX formato, onde X indica um conjunto de cadeias, por exemplo, "1", "2", ..., "X", "Y".

Estes são cada um armazenado em um char* chamado chromosome, como o arquivo é analisado.

O arquivo de texto é classificado na primeira coluna lexicographically, ou seja, eu vou ter um número de linhas que começam com "Chr1", e depois "chr2", etc.

Em cada entrada "chrX", eu preciso abrir outro ficheiro que está associado a esta entrada:

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

Eu tenho a função openSourceFile que é definido da seguinte forma:

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

O problema é que meus quits aplicativo com uma falha de segmentação vai desde o primeiro cromossomo para a segunda (de chr1 para chr2) na linha seguinte, onde eu fechar o primeiro arquivo cromossomo que eu abri:

fclose(merbaseIn);

Eu sei que não estou passando fclose um ponteiro NULL, porque até a falha de segmentação, eu estou lendo dados deste arquivo. Posso até quebrar isso em um condicional e eu ainda obter o Fault:

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

Além disso, eu sei obras openSourceFile (pelo menos para chr1, ao configurar a primeira alça de FILE* arquivo) porque meus parses aplicação chr1 linhas e lê dados do arquivo de origem FILE* corretamente.

O que é sobre esta chamada fclose que está causando uma falha de segmentação de ocorrer?

Foi útil?

Solução

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

É muito provável que o segfault é causada por corrupção de memória na pilha, e não algo que está afetando os habitantes locais. Valgrind irá mostrar-lhe imediatamente o primeiro acesso errado que você faz.

Edit: A opção --db-attach para valgrind foi preterido desde o lançamento 3.10.0 em 2014. O estado notas de lançamento:

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

Outras dicas

um aviso de erro i é esta linha:

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

que deve ser:

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

Isso ocorre porque uma seqüência tem um fechamento 0 no final que você também tem que dar espaço para

Melhor palpite é que alguma outra parte do seu código está corrompendo a memória através de uma saturação de buffer ou bug similar.

Embora pouco provável que seja a causa, você tem uma condição potencial de superação em sua matriz nome quando o nome completo do arquivo excede 100 caracteres.

Gostaria de sugerir o uso de um depurador para observar mudanças no local de memória usado pela variável merbaseIn.

Generic Ponteiro Problema

C é uma grande linguagem mas exige que você não espancar sua própria memória. Além do problema observado anteriormente, onde o malloc é 1 byte curto, você pode ter outros problemas de ponteiro.

Eu sugeriria usando um depurador de memória . No passado, elétrico da cerca era bastante popular, mas esses dias eu ouvir mais sobre valgrind . Há muitas outras opções.

Além de erro encontrado por reinier , eu suspeito que:

free(chromosome);

deve ser seguida por:

chromosome = NULL;

para evitar potencial uso de um valor não válido.

Por isso ARQUIVO ** filePtr se apenas neste FILE * filePtr seria suficiente? apenas um pensamento ...

valgrind com memcheck é definitivamente a ferramenta certa para descobrir a causa da falha de segmentação. Para usar um depurador com valgrind, nota que a opção --db-attach para valgrind ficou obsoleta desde o Valgrind 3.10.0 foi lançado em 2014. O estado notas de lançamento:

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

Revisão cada lugar que você usou "malloc" e veja se você cometeu um erro.

Por exemplo, eu estava colocando linhas lidos de um arquivo em um char **, mas eu incorretamente malloced-lo como:

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

Quando deveria ter sido:

my_list = malloc(sizeof(char*)* num_lines_found_in_file);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top