La mise en mémoire tampon des entrées/sorties (IO buffering) est présente dans le langage C depuis l'apparition de la bibliothèque standard (stdio). Elle a été introduite pour améliorer les performances des opérations de lecture et d'écriture, car les accès au disque ou aux périphériques sont une opération coûteuse en temps, et la mise en mémoire tampon permet de réduire leur nombre.
Une compréhension insuffisante du fonctionnement de la mise en mémoire tampon peut entraîner des délais inattendus lors des entrées/sorties, une perte de données lors d'un arrêt brutal du programme, des erreurs dans le travail avec plusieurs flux (en particulier avec stdout/stderr), ainsi que des erreurs de synchronisation entre les processus ou les systèmes.
Sachant que les flux de fichiers peuvent être mis en mémoire tampon, mis en mémoire tampon de manière linéaire ou non mis en mémoire tampon, il est important d'utiliser les fonctions de vidage explicite du tampon (fflush()), de fermer correctement les fichiers (fclose()), ainsi que de combiner correctement l'utilisation de stdin, stdout et stderr. La mise en mémoire tampon dépend également du type de flux (par exemple, stdout est vidé lors de l'impression du caractère \n dans un flux associé à un terminal, mais pas toujours — si c'est un fichier).
Exemple de code :
#include <stdio.h> int main() { printf("Hello"); // sleep(10); // jusqu'à fflush la sortie ne sera pas faite fflush(stdout); // affiche immédiatement le tampon à l'écran return 0; }
Caractéristiques clés :
fflush() — l'outil principal pour vider manuellement le tamponPeut-on compter sur le fait que la sortie de printf apparaîtra immédiatement à l'écran ?
Non, si la sortie n'est pas dirigée vers un terminal, mais par exemple vers un fichier, les lignes n'apparaîtront pas tant qu'un vidage du tampon n'est pas effectué ou que la limite de tampon n'est pas atteinte. Même dans un terminal, une ligne sans \n peut ne pas apparaître immédiatement. Utilisez fflush(stdout); pour afficher immédiatement.
Que se passe-t-il si l'on appelle fflush(stdin) ?
C'est un comportement indéfini selon la norme C. Certains compilateurs/plateformes peuvent vider le tampon du flux d'entrée, mais ce n'est pas garanti par la norme, et cette méthode n'est pas portable et potentiellement dangereuse.
Peut-on considérer printf et fprintf(stderr, ...) comme équivalents pour une sortie immédiate ?
Non. La sortie standard (stdout) est généralement complètement ou par ligne tamponnée, alors que stderr est toujours non tamponnée par défaut. C'est-à-dire que la sortie dans stderr apparaît immédiatement à l'écran, tandis que pour stdout, ce n'est pas le cas.
fflush(stdin) pour vider le tampon d'entréeUn programme écrit un fichier journal via printf, mais n'appelle pas fflush(stdout) et ne ferme pas le fichier lors d'un arrêt abrupt.
Avantages :
Inconvénients :
Un programme appelle fflush(stdout) après chaque enregistrement de journal important, ou écrit des messages critiques dans stderr.
Avantages :
Inconvénients :