fclose () provocando falha de segmentação
-
22-07-2019 - |
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?
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);