Question

J'utilise souvent le site Web www.cplusplus.com comme référence pour l'écriture de code C.

Je lisais l'exemple cité sur la page pour fread . et avait une question.

Par exemple, ils publient:

/* 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;
}

Il me semble que si résultat! = lSize, alors free (buffer) ne sera jamais appelé. Serait-ce une fuite de mémoire dans cet exemple?

J'ai toujours pensé que les exemples sur leur site étaient d'une très grande qualité. Je ne comprends peut-être pas correctement?

Était-ce utile?

La solution

Il ne s'agirait pas d'une fuite de mémoire dans cet exemple , car arrêter le programme (en appelant exit()) libère toute la mémoire qui lui est associée.

Cependant, ce serait une fuite de mémoire si vous utilisiez ce morceau de code comme sous-programme et appelez quelque chose comme return 1; à la place de <=>.

Autres conseils

Techniquement, oui, c’est une fuite de mémoire. Cependant, toute mémoire allouée par un processus est automatiquement libérée à la fin de ce processus. Par conséquent, dans cet exemple, les appels à libérer (et à fermer) ne sont pas vraiment nécessaires.

Dans un programme plus complexe, ce serait probablement un réel problème. Le manque manquant créerait une fuite de mémoire et le fclose manquant causerait une fuite de ressources.

Le système d'exploitation nettoie toute mémoire non libérée par un processus à la fermeture de ce processus. Au moins, les systèmes d’exploitation modernes le font.

Si le programme ne se terminait pas au point résultat! = lSize, c’est-à-dire qu’il continuait avec un autre chemin d’exécution, alors oui, c’est une fuite de mémoire garantie.

Il existe deux chemins possibles.

(1) result! = lSize - dans ce cas, exit (0) est appelé. Cela tue le processus et le système d'exploitation nettoie la mémoire.

(2) result == lsize - dans ce cas, la mémoire tampon est explicitement libérée, mais return est appelé juste après. free est donc généralement juste un bon style, car cela tue également le processus et le système d'exploitation nettoie à nouveau. la mémoire.

Donc, dans ce cas simple, il n’ya pas de fuite de mémoire. Mais il est probablement recommandé de s’assurer que vous libérez la mémoire allouée dans l’application que vous écrivez. Cette habitude vous évitera de nombreux maux de tête à l’avenir.

En ce qui concerne les fuites de mémoire possibles, d’autres ont déjà répondu à cette question. Il y a quelque temps, j'ai publié une variante du code donné qui devrait gérer correctement toutes les conditions d'erreur possibles:

.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top