Pregunta

A menudo uso el sitio web www.cplusplus.com como referencia cuando escribo el código C.

Estaba leyendo el ejemplo citado en la página para fread y tenía una pregunta.

Como ejemplo publican:

/* fread example: read a complete file */
#include <stdio.h>
#include <stdlib.h>

int main () {
  FILE * pFile;
  long lSize;
  char * buffer;
  size_t result;

  pFile = fopen ( "myfile.bin" , "rb" );
  if (pFile==NULL) {fputs ("File error",stderr); exit (1);}

  // obtain file size:
  fseek (pFile , 0 , SEEK_END);
  lSize = ftell (pFile);
  rewind (pFile);

  // allocate memory to contain the whole file:
  buffer = (char*) malloc (sizeof(char)*lSize);
  if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

  // copy the file into the buffer:
  result = fread (buffer,1,lSize,pFile);
  if (result != lSize) {fputs ("Reading error",stderr); exit (3);}

  /* the whole file is now loaded in the memory buffer. */

  // terminate
  fclose (pFile);
  free (buffer);
  return 0;
}

Me parece que si resultado! = lSize, nunca se llamará a free (buffer). ¿Sería esto una pérdida de memoria en este ejemplo?

Siempre he pensado que los ejemplos en su sitio son de muy alta calidad. ¿Quizás no estoy entendiendo correctamente?

¿Fue útil?

Solución

No sería una pérdida de memoria en este ejemplo , porque al finalizar el programa (llamando a exit()) se libera toda la memoria asociada con él.

Sin embargo, sería una pérdida de memoria si usara este fragmento de código como una subrutina y llamara algo así como return 1; en lugar de <=>.

Otros consejos

Técnicamente, sí, es una pérdida de memoria. Pero cualquier memoria asignada por un proceso se libera automáticamente cuando ese proceso finaliza, por lo que en este ejemplo las llamadas a liberar (y fclose) no son realmente necesarias.

En un programa más complejo, esto probablemente sería un problema real. La falta libre crearía una pérdida de memoria y la falta de fclose causaría una pérdida de recursos.

El sistema operativo limpia cualquier memoria no liberada por un proceso cuando ese proceso se cierra. Al menos, los sistemas operativos modernos lo hacen.

Si el programa no saliera en el punto de resultado! = lSize, es decir, continuó con alguna otra ruta de ejecución, entonces sí, es una pérdida de memoria garantizada.

Hay dos caminos posibles.

(1) result! = lSize - en este caso, se llama a exit (0). Esto mata el proceso y el sistema operativo limpiará la memoria.

(2) result == lsize: en este caso, el búfer se libera explícitamente, pero luego se llama a return, por lo que free es principalmente un buen estilo porque esto también mata el proceso y el sistema operativo, nuevamente, limpiará hasta la memoria.

Entonces, en este caso simple, no hay pérdida de memoria. Pero probablemente sea una buena práctica asegurarse de que está liberando cualquier memoria que haya asignado en cualquier aplicación que escriba. Entrar en este hábito evitará muchos dolores de cabeza en el futuro.

En cuanto a la posible pérdida de memoria, otros ya han respondido esa pregunta. Hace un tiempo, publiqué una variación del código dado que debería manejar correctamente todas las posibles condiciones de error:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top