En primer lugar, soy consciente de que la apertura de un archivo con fopen() y no el cierre es terriblemente irresponsable y mala forma. Esto es sólo pura curiosidad, así que por favor humor mí 🙂

Sé que si un programa en C se abre un montón de archivos y nunca se cierra, alguna de ellas, eventualmente, fopen() va a comenzar a fallar. Hay otros efectos secundarios que pueden causar problemas fuera el propio código? Por ejemplo, si tengo un programa que abre un archivo y, a continuación, sale sin cierre, que podrían causar un problema para la persona que ejecuta el programa? Sería un programa de pérdida de algo (de la memoria, los identificadores de archivo)? Podría haber problemas de acceso que el archivo de nuevo una vez que el programa había terminado? ¿Qué pasaría si el programa se ejecuta muchas veces en la sucesión?

  • No hay necesidad de que todas las exenciones de responsabilidad. No hay nada terriblemente mal por salir sin llamar fclose, por lo menos no más que el uso de goto. Todo depende de la situación.
InformationsquelleAutor electrodruid | 2011-11-17

4 Comentarios

  1. 75

    Mientras se ejecuta el programa, si se mantiene la apertura de los archivos sin cerrar, el resultado más probable es que se ejecute fuera de descriptores de archivo/controladores disponibles para su proceso, y el intento de abrir más archivos de fracasar con el tiempo. En Windows, esto también puede evitar que otros procesos de apertura o eliminación de los archivos que se han abierto, ya que por defecto, los archivos se abren en un exclusivo modo de compartir que impide que otros procesos de apertura de los mismos.

    Una vez que el programa se cierra, el sistema operativo va a limpiar después de ti. Se va a cerrar todos los archivos que queda abierto cuando se termina su proceso, y realizar cualquier otro tipo de limpieza que es necesario (por ejemplo, si un archivo fue marcada eliminar al cierre, se elimina el archivo, a continuación,; tenga en cuenta que ese tipo de cosas es específico de la plataforma).

    Sin embargo, otra cuestión a tener cuidado es el búfer de datos. La mayoría de las secuencias de archivo de búfer de datos en la memoria antes de que se escriben en el disco. Si usted está usando FILE* arroyos de la stdio la biblioteca, entonces hay dos posibilidades:

    1. Su programa sale normalmente, ya sea llamando a la exit(3) función, o mediante la devolución de main (que implícitamente se llama exit(3)).
    2. Su programa sale de manera anormal; esto puede ser a través de llamadas abort(3) o _Exit(3), muriendo de una señal/excepción, etc.

    Si el programa sale normalmente, el tiempo de ejecución de C se encargará de flushing cualquier búfer de las secuencias que se han abierto. Así que si usted tiene el búfer de datos escritos en la FILE* que no estaba vacía, va a ser vaciado normal de salida.

    Por el contrario, si el programa sale de forma anormal, cualquier búfer de datos se no se vacían. El OS dice: «¡oh querida me dejó un descriptor de archivo abierto, que mejor cierre que para usted» cuando termine el proceso; no tiene idea de que hay algunos datos aleatorios agazapado en algún lugar en la memoria que el programa de la intención de escribir en el disco, pero no lo hizo. Así que tenga cuidado acerca de eso.

    • Las conjeturas sobre cuánto tiempo haría que dejó más de búfer de existir antes de ser recuperado por el sistema operativo?
    • Me imagino tan rápido como sea posible, ya que el buffer no es mágico – su programa de memoria asignada para ello, y OS debería liberar esa memoria cuando el programa se bloquea como parte del proceso normal de limpieza.
  2. 12

    El C estándar dice que el llamamiento exit (o, equivalentemente, de regreso de main) hace que todos los abiertos FILE objetos a ser cerrado como si por fclose. Así que esto está perfectamente bien, excepto que usted perderá la oportunidad de detectar los errores de escritura.

    EDICIÓN: no Existe garantía para anormal terminación (abort, un error de assert, la recepción de una señal cuyo comportamiento predeterminado es anormalmente terminar el programa … se nota que no hay necesariamente ninguna de tales señales, y otras de aplicación definidos por el medio). Como otros han dicho, los sistemas operativos modernos va a limpiar todos los visible externamente recursos, tales como nivel de SO identificadores de archivo, a pesar de todo; sin embargo, FILEs es probable no se vacían en ese caso.

    Existen, sin duda, han sido Aquellos que no limpiar externamente visibles de los recursos de terminación anormal; tiende a ir junto con no cumplir duro privilegio límites entre el «núcleo» y «usuario» y/o entre los distintos espacio de usuario «procesos», simplemente porque si usted no tiene esos límites no puede ser posible para hacerlo de manera segura en todos los casos. (Pensemos, por ejemplo, ¿qué sucede si usted escribe la basura más de la abrir-archivo de la tabla en MS-DOS, ya que son perfectamente capaces de hacer.)

    • Podría proporcionar una referencia, ¿por qué no ser esto OS específica?
    • C99, §7.20.4.3, ¶ 4: «a continuación, todas las corrientes de aguas abiertas con no escritas búfer de datos se vacían, todas las corrientes de aguas abiertas se cierran, y todos los archivos creados por la función tmpfile se quitan.» Tenga en cuenta que esto sólo se aplica a regular (exit, return de main) la terminación, lo que sucede con _Exit & co. es de aplicación definido.
    • gracias, pero también es cierto que, si el proceso finaliza de forma inesperada por alguna otra razón, entonces la mayoría de los modernos sistemas operativos para limpiar las manijas y la memoria de todos modos.
    • claro que sí, pero, ya que usted quería una multiplataforma de referencia de este hecho, yo siempre solo de las garantías dadas por la norma. 🙂
    • Justo lo suficiente 🙂
    • Genial, gracias por aclarar 🙂

  3. 4

    Suponiendo que salir bajo control, con el exit() llamada al sistema o que regresan de main(), a continuación, abrir el archivo de secuencias se cerró después de la limpieza. El Estándar de C (y POSIX) este mandato.

    Si la salida de control (core dump, SIGKILL), etc, o si utiliza _exit() o _Exit(), a continuación, abrir el archivo de secuencias no se vacían (pero los descriptores de archivo final cerrado, suponiendo un POSIX-como el sistema de descriptores de archivo Estándar de C no tiene el mandato de descriptores de archivo). Tenga en cuenta que _Exit() es exigido por el estándar C99, pero _exit() es obligatorio por POSIX (pero se comportan de la misma en sistemas POSIX). Tenga en cuenta que los descriptores son independientes de las secuencias de archivo. Ver la discusión de las Consecuencias de la Terminación del Programa’ en el POSIX página para _exit() para ver lo que sucede cuando un programa termina bajo Unix.

    • «pero los descriptores de archivo final cerrado» – ¿estás seguro? La norma dice que «Si las corrientes de aguas abiertas con no escritas búfer de datos se vacían, de corrientes de aguas abiertas se cierran, o la eliminación de los archivos temporales de la implementación definido». (C99 §7.20.4.4 ¶2)
    • Los flujos no son cerradas; los descriptores de archivo son. Hay una (gran) diferencia. Todos los descriptores de archivo se cierra cuando finaliza un programa, consulte la «Consecuencias de la Terminación del Programa’ en el _Exit() página referenceI estoy haciendo la suposición de que el sistema proporciona POSIX-como la semántica; en puro estándar de C, no hay descriptores de archivo. El comportamiento no-POSIX sistemas puede ser un poco diferente.
    • Eso es lo que estoy diciendo: en cuanto al estándar de C es de que se trate, lo que sucede en _Exit() de la implementación definido (y uno de los posibles comportamientos es el exigido por el estándar POSIX).
  4. 0

    Cuando el proceso se muere, la mayoría de los sistemas operativos modernos (el núcleo específicamente) se libre de todos los mangos y la memoria asignada.

    • Un típico sistema operativo moderno hará que, al menos. Mi entendimiento es que de vuelta en el día, Windows 3.1 y lo que no le salía controla si la aplicación no se cerró correctamente. Y puede haber algunos otros muy mínima del sistema operativo en estos días (sistemas embebidos, tal vez) que no encargamos de eso.
    • que sería de aplicación para OS identificadores de archivo, difícil, debido a que el estándar (como @Zack dijo) garantiza que en la de terminación de la CRT FILE * están cerradas en caso de regular la salida.
    • Buen punto, aunque como te dicen arriba, el CRT no es garantía de que las asas se puede cerrar si se sale de la aplicación anormalmente. Normalmente el sistema operativo que hace que – y a mi entender, que hay algunos muy viejos o muy especializadas de los sistemas operativos que no hacer que esa garantía.

Dejar respuesta

Please enter your comment!
Please enter your name here