J'ai donc creusé comment la partie STDIO de Libc est mise en œuvre et que j'ai rencontré une autre question. En regardant Lorsque la première opération d'E / S se produit sur
Un fichier, MALLOC (3) est appelé, et un
tampon est obtenu. p>
BlockQuote> Ceci est logique, votre programme ne doit pas avoir de mais strong>, vous pouvez spécifier votre propre tampon ... p> man setvbuf code> Je vois ce qui suit:
Malloc Code> pour I / O Sauf si vous l'utilisez réellement. Ma réaction intestinale à ceci est que libc nettoie son propre gâchis ici. Ce que je peux supposer que cela ne fait que le valgrind ne signale aucune fuite de mémoire (ils pourraient bien sûr faire quelque chose de sale et ne pas l'allouer via
malloc code> directement ... mais nous supposerons que cela utilise littéralement
MALLOC code> pour l'instant). P>
setvbuf(stdout, 0, _IOFBF, 0);
printf("hello ");
setvbuf(stdout, 0, _IOLBF, 0);
printf("world\n");
3 Réponses :
Aussi à partir du Page de manuel (au moins, sur mon système): p>
Si buf n'est pas nul, c'est la responsabilité de l'appelant de libérer (3) ce tampon après la fermeture du flux. p> blockQuote>
C'est-à-dire que vous êtes maloc-le, vous libérez-le. P>
Avant de quitter, vous pouvez fermer les flux vous-même, vous permettant ainsi de libérer le tampon. Alternativement, vous pouvez affleurer les flux et appeler
SETVBUF code> à nouveau avec un argument de mémoire tampon null code> NULL code> pour revenir à un tampon géré de la bibliothèque ou des E / S sans déformer. P>
Réponse mise à jour pour créer un lien vers la page. C'est OS X, mais la page d'homme vient de FreeBSD ( FreeBSD.org/cgi/ Man.Cgi? Query = SetVbuf ).
Difficile de voir comment les choses pourraient être autrement, comme on pourrait fournir un tampon statique qui ne doit pas être libre avec libre ().
@Neil: En effet, je me demandais plus si la STDLIB avait une fuite de mémoire par design puisqu'il n'y a aucun moyen d'obtenir le tampon qu'il a alloué à partir du flux.
Appelant " SETVBUF code> à nouveau avec un argument de tampon NULL" n'est pas autorisé par la norme (voir citation dans ma réponse).
Vous pouvez fermer Avec la plupart des systèmes d'exploitation, la mémoire du tas est automatiquement publiée lors de la sortie du programme. Donc, il n'y a pas de problème pratique avec des tampons induits (il existe un problème cosmétique, qui est que ces tampons inédites polluent la production de Valgrind). Mon conseil serait d'utiliser des tampons statiques si vous ressentez l'envie d'appeler stdin code>,
stdout code> et
starr code> explicitement (avec
fcFose () code>). P >
SETVBUF () code> sur l'entrée ou la sortie standard. Les tampons statiques ne doivent pas être alloués ou libérés et sont appropriés ici car il n'y a que trois flux standard et que vous vous inquiétez d'une situation où ces flux sont tenus ouverts à la fin du programme. P>
La sortie de débogage polluée est un problème, car vous obtenez l'habitude de briller sur la sortie et vous pouvez facilement manquer une erreur réelle.
@THOMAS: Y a-t-il une garantie que les fichiers seront fermés avant la libération de la mémoire?
@outis: sur les systèmes d'exploitation où la mémoire est automatiquement publiée, il est publié "atomiquement", à un point où le ou les filets d'exécution ont cessé d'exister. Il n'y a rien qui peut fonctionner après cela, en particulier aucun code LIBC qui pourrait (à tort) accéder au tampon libéré. En bref, il "fonctionne juste". Il pourrait toujours y avoir des fichiers ouverts et des données tamponnées, mais dans le noyau OS, en dehors de la portée du code d'application.
Au moins en fonction de la norme C, votre dernier scénario n'est tout simplement pas autorisé: "La fonction SETVBUF ne peut être utilisée qu'après que le flux pointé par le flux a été associé à un fichier ouvert et avant toute autre opération (autre que Un appel infructueux à SETVBUF) est effectué sur le flux. " (C99, § 7.19.5.6 / 2). P>
sur le point de libérer la mémoire dans les cas simples, il faut appeler atexit () code> pour enregistrer un rappel qui libérera la mémoire après la sortie de
Main () code>, mais avant que le contrôle ne soit renvoyé au système d'exploitation. P>
intéressant. Donc, mon dernier exemple tombe dans la catégorie de comportement indéfini.