Tamponné et non de flux
En cas de tampon de flux il l'a dit dans un livre que c'attendre jusqu'à ce que le tampon est plein d'écrire de nouveau à l'écran. Par exemple:
cout << "hi";
- Que veulent-ils dire par "la mémoire tampon est pleine".
cerr << "hi";
- Il est dit dans mon livre que tout envoyé à
cerr
est écrit à la norme de l'erreur immédiatement l'appareil, ce qui veut dire?char *ch; cin>> ch; //I typed "hello world";
- Dans cet exemple
ch
sera attribué à "bonjour" et "monde" sera ignoré veut-il dire qu'il a encore en mémoire tampon et il aura une incidence sur les résultats futurs états?
Standard remarque: par défaut
En fait, dans le deuxième exemple, vous aurez à écrire dans la mémoire à un endroit inconnu et provoquer un comportement non défini...**espère** résultant dans un accident.
cout
est synchronisé avec stdio
, et par défaut stdio
est de ligne-mis en mémoire tampon.En fait, dans le deuxième exemple, vous aurez à écrire dans la mémoire à un endroit inconnu et provoquer un comportement non défini...**espère** résultant dans un accident.
OriginalL'auteur AlexDan | 2012-05-09
Vous devez vous connecter pour publier un commentaire.
Votre livre ne semble pas très utile.
1) Les flux de sortie de leur envoyer des octets à un
std::streambuf
, ce qui peutcontenir un tampon; la
std::filebuf
(dérivé destreambuf
) utilisé paret
std::ofstream
seront généralement mis en mémoire tampon. Cela signifie que lorsque l'la sortie d'un personnage, il n'est pas nécessairement la sortie immédiatement; il
être écrites dans une mémoire tampon, et la sortie pour le système d'exploitation uniquement lorsque la mémoire tampon est
complet, ou vous demande explicite d'une certaine façon, généralement par l'appelant
flush()
sur le flux (directement, ou indirectement, par l'utilisation destd::endl
).Cela peut varier, cependant, la sortie de
std::cout
est synchronisé avecstdout
, et la plupart des implémentations plus ou moins à suivre les règles destdout
pourstd::cout
, la modification de la stratégie de mise en mémoire tampon si la sortieva un dispositif interactif.
En tout cas, si vous n'êtes pas sûr, et vous voulez être sûr que la sortie
vraiment laisser votre programme, il suffit d'ajouter un appel à la chasse.
2) Votre livre est mauvais ici.
L'une des stratégies de mise en mémoire tampon est
unitbuf
; c'est un indicateur dans l'std::ostream
que vous pouvez définir ou réinitialiser (std::ios_base::set()
etstd::ios_base::unset()
—std::ios_base
est une classe de base destd::ostream
, de sorte que vous pouvez appeler ces fonctions sur unstd::ostream
de l'objet). Lorsque
unitbuf
est définie,std::ostream
ajoute un appel àflush()
à la fin de chaque sortie de la fonction, de sorte que lorsque vous écrivez:
le flux sera rincé après tous des caractères de la chaîne
sont de sortie, à condition
unitbuf
est réglé. Sur les start-up,unitbuf
est réglépour
std::cerr
; par défaut, il n'est pas fixé sur n'importe quel autre fichier. Mais voussont libres de définir ou désactiver comme vous le souhaitez. Je déconseille
décharger sur
std::cerr
, mais sistd::cout
est sortie à undispositif interactif, il fait beaucoup de sens pour définir s'il en existe.
Noter que tout ce qui est en question ici est la mémoire tampon dans le
streambuf
.Généralement, le système d'exploitation également des tampons. Tous rinçage de la mémoire tampon n'est
transférer les caractères de l'OS, ce qui signifie que vous ne pouvez pas utiliser
ofstream
directement lors de l'intégrité transactionnelle est nécessaire.3) Lors de la saisie d'une chaîne de caractères ou un tampon de caractères à l'aide de
>>
, l'std::istream
premier saute menant espace blanc, puis les entrées jusqu'àmais pas y compris le prochain espace blanc. Dans les termes formels de la
la norme, c' "extraits" les caractères à partir du flux, de sorte qu'ils
ne sera pas vu de nouveau (à moins que vous chercher, si le flux de données prend en charge).
La prochaine entrée de ramassage à l'endroit où le précédent arrêté. Si
les caractères suivants sont dans une mémoire tampon, ou encore sur le disque, c'est vraiment
hors de propos.
Noter que la mise en mémoire tampon d'entrée est un peu complexe, en ce qu'il se produit
à différents niveaux, et au niveau de l'OS, il prend différentes
les formes en fonction de l'appareil. Généralement, le système d'exploitation de la mémoire tampon d'un fichier par
secteurs, souvent la lecture de plusieurs secteurs à l'avance. L'OS sera toujours
retour autant de caractères comme l'ont exigé, à moins qu'il rencontre à la fin de
fichier. La plupart des OSs sera un tampon clavier en ligne: pas de retour d'un
demande de lecture jusqu'à ce qu'une ligne complète a été saisi, et de ne jamais revenir
les caractères au-delà de la fin de la ligne courante dans une demande de lecture.
De la même manière que
std::ostream
utilise unstreambuf
pour la sortie,std::istream
utilise un seul caractère. Dans le casde
std::cin
, normalement, c'est unefilebuf
; lorsque leistream
les demandes d'un personnage, le
filebuf
le retour de sa mémoire tampon siil en a un; s'il ne le fait pas, il va tenter de remplir la mémoire tampon,
en demandant par exemple 512 (ou quelle que soit sa taille de la mémoire tampon est), les personnages de la
OS. Qui réagira en fonction de sa mise en mémoire tampon de la politique de la
de l'appareil, comme décrit ci-dessus.
En tout cas, si
std::cin
est connecté au clavier, et vous aveztapé
"hello world"
, tous les caractères que vous avez saisis seront luspar le flux de la finalement. (Mais si vous êtes en utilisant
>>
, il y aura beaucoupdes espaces qui vous de ne pas voir.)
OriginalL'auteur James Kanze
flux en C++ sont de tampon pour augmenter l'efficacité, qui est le fichier de console et de IO est très lente en comparaison à des opérations de mémoire.
Pour lutter contre ce C++ ruisseaux ont un tampon (une banque de mémoire) qui contient tout ce qui est à écrire dans le fichier de sortie ou, lorsqu'il est complet, alors il vidées dans le fichier. L'inverse est vrai pour l'entrée, il récupère plus quand il le tampon est vide.
C'est très important pour les cours d'eau, car les suivantes
Serait de 4 écrit dans un fichier qui est inefficace.
Toutefois, dans le cas de std::cout, cin, et eree alors ce type ont réellement mise en mémoire tampon par défaut désactivé pour s'assurer qu'il peut être utilisé en conjonction avec std::printf et std::place etc...
Pour l'activer de nouveau (que je vous recommande de les faire):
Mais ne pas utiliser de style C sortie de la console, alors qu'il est défini sur false ou les mauvaises choses peuvent arriver.
bien "1hello monde\n" seront écrites dans la mémoire tampon, il sera écrit à l'écran lors de l'entrée est veux de l'utilisateur, cin les opérations d'extraction de synchroniser les deux cours d'eau provoquant cout de rincer. Lorsque vous manuellement vider le flux en utilisant std::cout << std::flush ou std::cout << std::endl; Ou lorsque le flux est détruit, & fermé (c'est à dire de fin de programme pour le std::cout ou à la fin de la portée pour les fichiers).
Eree et Cout diffèrent par le descripteur de fichier, ils sont envoyés trop, cout va vers stdout et eree va à stderror. lorsque vous définissez pas de synchronisation avec stdio puis ils ont tous deux un tampon, quand c'est vrai, alors ils sont tous les deux barrettes de mémoire. Cela dit
clog
est le même quecerr
mais je crois toujours en mémoire tampon.J'ai juste essayé avec GCC et il semble que dans de GCC que std::eree est toujours unbuffered même avec std::ios_base::sync_with_stdio(false).
OriginalL'auteur 111111
Vous pouvez vérifier les différences de vous-même avec un petit app.
Essayer la différence entre les deux "Démarrer" relevés, puis changer pour la eree. La différence est due à la mise en mémoire tampon.
L'instruction prend environ 2 secondes sur ma plate-forme, vous pourriez avoir besoin de modifier l'i < condition sur le vôtre.
Si vous obtenez ce résultat de la façon dont il est écrit ici, vous avez un tampon std::cout.
Ou un ralentissement de la console. Comme, sous windows 🙂
+1 pour l'exemple. Mieux qu'une illustration, comme on dit 🙂
OriginalL'auteur Captain Giraffe
Avec tampon de sortie il y a une région de la mémoire tampon, où les choses que vous écrivez est stocké avant qu'il soit écrit à la sortie. Quand vous dites
cout << "hi"
la chaîne est probablement seulement copiées dans la mémoire tampon et pas écrite. cout attend généralement jusqu'à ce que la mémoire a été rempli avant qu'il en fait commence à écrire des choses.La raison pour cela est parce que généralement le processus de départ à l'écriture de données est lente, et donc, si vous faites cela pour chaque caractère que vous obtenez terrible de la performance. Un tampon est utilisé de sorte que le programme n'a qu'à le faire trop souvent et de vous obtenir de bien meilleures performances.
Cela signifie simplement qu'aucune zone tampon n'est utilisé. eree peut toujours envoyer des " h " et " i " en même temps, car il a déjà deux d'entre eux.
Cela n'a rien à voir avec mise en mémoire tampon. l'opérateur >> char* est défini à lire jusqu'à ce qu'il voit d'espaces, de sorte qu'il s'arrête à l'espace entre "bonjour" et "monde". Mais oui, la prochaine fois que vous lisez, vous obtiendrez "monde".
(bien que si ce code n'est pas juste une paraphrase de la actuall code puis il a un comportement indéfini parce que vous êtes en train de lire le texte dans un emplacement de mémoire non défini. Au lieu de cela, vous devriez faire:
)
OriginalL'auteur bames53
Chaque appel d'écriture vers le terminal est lent, de sorte à éviter de faire ralentir les choses, souvent, les données sont stockées dans la mémoire jusqu'à ce qu'une certaine quantité de données a été saisi ou le tampon est vidé manuellement avec fflush ou std::endl. Le résultat de ceci est parfois que le texte ne pourrait pas être écrit dans le terminal au moment où vous l'attendez.
Depuis le moment de messages d'erreur est plus importante que la normale de sortie, le gain de performance est ignoré et les données ne sont pas mises en mémoire tampon. Cependant, depuis une chaîne est passée en un seul morceau de données, il est écrit dans un appel (à l'intérieur d'une boucle quelque part).
Il monde serait toujours dans la mémoire tampon, mais il est assez facile de le prouver par vous-même en train de l'essayer dans un 3 ligne de programme. Cependant, votre exemple échoue puisque vous êtes une tentative d'écriture dans la mémoire non allouée. Vous devriez être en prenant d'entrée dans un std::string à la place.
filebuf
destd::cerr
encore des tampons comme d'habitude. La différence est queunitbuf
est activé, ce qui signifie que leostream
fait une chasse d'eau à la fin de chaque>>
. (En fait, dans le destructeur de la sentinelle objet construit au sommet de la fonction.)sont les seules choses qui font que le tampon est vidé fflush ot std::endl; ? qu'en cout << "bonjour"; cout << "tout le monde";
Pas de. Sauf
unitbuf
est définie, dans ce cas, il y aura une chasse d'eau à la fin de chaque " <<".OriginalL'auteur Catskul