fclose() causando falla de segmentación

5 minutos de lectura

Tengo un archivo de texto delimitado por tabuladores que estoy analizando. Su primera columna contiene cadenas del formato chrXdonde X denota un conjunto de cadenas, por ejemplo, “1”, “2”, …, “X”, “Y”.

Cada uno de ellos se almacena en un char* llamado chromosomea medida que se analiza el archivo.

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

En cada entrada “chrX”, 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 funcion 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 (del chr1 para chr2) en la siguiente línea, donde cierro el primer archivo de cromosomas que abrí:

fclose(merbaseIn);

se que no paso 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é openSourceFile funciona (al menos para chr1al configurar el primer identificador de archivo de FILE*) porque mi aplicación analiza chr1 filas y lee datos del FILE* archivo fuente correctamente.

que tiene esto fclose llamada que está causando una falla de segmentación?

fclose causando falla de segmentacion
jonathan graehl

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

Es muy probable que la falla de segmento se deba a la corrupción de la memoria en el montón, no a algo que afecte a los locales. Valgrind le mostrará inmediatamente el primer acceso incorrecto que realice.

Editar: El --db-attach opción a valgrind ha quedado obsoleto 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

  • yo no estaba corriendo free en los punteros dentro del puntero doble. Tampoco estaba liberando punteros en otros lugares. Deseché esta aplicación y la escribí desde cero, ejecutando valgrind a medida que avanzaba para asegurarme de que estaba administrando la memoria correctamente. ¡Gracias por señalarme esta herramienta!

    – Alex Reynolds

    18 de septiembre de 2009 a las 11:10

  • Sí, valgrind me enseñó: 1) que todos tenían razón y que solo debería haber usado punteros inteligentes (auto/refcount, etc.) o recolección de basura y 2) con valgrind en realidad no necesito recolección de basura. La única salvedad es la cobertura de la prueba. Creo que es más fácil encontrar fugas de memoria con valgrind que con cualquier herramienta para lenguajes GC (por ejemplo, lenguajes JVM o .NET) con los que estoy familiarizado.

    –Jonathan Graehl

    18 de septiembre de 2009 a las 17:46

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 para el que también debe dejar espacio.

  • Cierto, pero strlen() devuelve size_t, así que descarta esa conversión. Y malloc() devuelve void *, que se puede convertir a cualquier otro tipo de puntero (datos) en C, así que suelte esa conversión también.

    – relajarse

    18 de septiembre de 2009 a las 8:39

  • En este caso, puede usar strdup() para reemplazar malloc()+strcpy().

    – usuario172818

    18 de septiembre de 2009 a las 8:45

  • No estoy de acuerdo con el elenco (char *) que establece claramente la intención.

    – Sapo

    18 de septiembre de 2009 a las 8:47

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

Aunque es poco probable que sea la causa, tiene una posible condición de saturación 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 la memoria utilizada por la variable merbaseIn.

Problema de puntero genérico

C es un gran lenguaje pero requiere que no golpees tu propia memoria. Además del problema mencionado anteriormente donde el malloc tiene 1 byte corto, es posible que tenga otros problemas con el puntero.

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

fclose causando falla de segmentacion
muviciel

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

free(chromosome);

debe ser seguido por:

chromosome = NULL;

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

1647688747 52 fclose causando falla de segmentacion
Mandrágora

¿Por qué este ARCHIVO** filePtr si solo este ARCHIVO* filePtr sería suficiente? solo un pensamiento…

1647688747 710 fclose causando falla de segmentacion
yarda dan

valgrind con memcheck es definitivamente la herramienta adecuada para descubrir la causa de la falla de segmentación. Para usar un depurador con valgrindtenga en cuenta que el --db-attach opción a valgrind ha quedado obsoleto 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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad