Pregunta

Tengo un archivo de texto delimitado por tabulaciones que estoy analizando. Su primera columna contiene cadenas del formato chrX , donde X denota un conjunto de cadenas, por ejemplo, "1", "2", ..., " X '', '' Y ''.

Estos se almacenan en un char * llamado cromosoma , a medida que se analiza el archivo.

El archivo de texto se ordena en la primera columna lexicográficamente, es decir, tendré una serie de filas que comienzan con " chr1 " ;, y luego " chr2 " ;, etc.

En cada " chrX " entrada, necesito abrir otro archivo asociado con 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

Tengo la función openSourceFile que se define de la siguiente manera:

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

El problema es que mi aplicación se cierra con una falla de segmentación que va del primer cromosoma al segundo (de chr1 a chr2 ) en la siguiente línea, donde cierro el primer archivo cromosómico que abrí:

fclose(merbaseIn);

Sé que no voy a pasar a fclose un puntero NULL, porque hasta la Falla de segmentación, estoy leyendo datos de este archivo. Incluso puedo envolver esto en un condicional y todavía obtengo la falla:

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

Además, sé que openSourceFile funciona (al menos para chr1 , al configurar el primer identificador de archivo de FILE * ) porque mi aplicación analiza las filas chr1 y lee los datos del archivo fuente FILE * correctamente.

¿Qué tiene esta llamada fclose que está causando una falla de segmentación?

¿Fue útil?

Solución

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

Es muy probable que el defecto de seguridad sea causado por corrupción de memoria en el montón, no por nada que afecte a los locales. Valgrind le mostrará inmediatamente el primer acceso incorrecto que realice.

Editar: La opción --db-attach para valgrind ha quedado en desuso desde la versión 3.10.0 en 2014. Las notas de la versión indican:

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

Otros consejos

un error que noto es esta línea:

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

que debería ser:

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

Esto se debe a que una cadena tiene un 0 de cierre al final que también debe dejar espacio para

La mejor suposición es que alguna otra parte de su código está corrompiendo la memoria a través de un desbordamiento del búfer o un error similar.

Aunque es poco probable que sea la causa, tiene una posible condición de desbordamiento en su matriz de nombre de archivo cuando el nombre de archivo completo supera los 100 caracteres.

Sugeriría usar un depurador para observar los cambios en la ubicación de memoria utilizada por la variable merbaseIn.

Problema de puntero genérico

C es un gran lenguaje pero requiere que no golpee su propia memoria. Además del problema previamente observado donde el malloc es de 1 byte corto, puede tener otros problemas de puntero.

Sugeriría utilizando un depurador de memoria . En el pasado, Valla eléctrica era bastante popular, pero en estos días yo escucha más sobre valgrind . Hay muchas otras opciones.

Además del error encontrado por reinier , sospecho que:

free(chromosome);

debe ir seguido de:

chromosome = NULL;

para evitar el uso potencial de un valor que ya no es válido.

¿por qué este FILE ** filePtr si solo este FILE * filePtr fuera suficiente? solo un pensamiento ...

valgrind con memcheck es definitivamente la herramienta adecuada para descubrir la causa de la falla de segmentación. Para usar un depurador con valgrind , tenga en cuenta que la opción --db-attach a valgrind ha quedado en desuso desde que se lanzó Valgrind 3.10.0 en 2014. Las notas de la versión indican:

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

Revise cada lugar que utilizó " malloc " y vea si cometió un error.

Por ejemplo, estaba poniendo líneas leídas de un archivo en un char **, pero incorrectamente mallocedido como:

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

Cuándo debería haber sido:

my_list = malloc(sizeof(char*)* num_lines_found_in_file);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top