10
votes

Question de défaut de segmentation

J'ai observé que parfois dans des programmes C, si nous avons un printf dans le code n'importe où avant une erreur de segmentation, elle n'imprime pas. Pourquoi est-ce?


1 commentaires

Je vois souvent des anglophones non indigènes utilisent la phrase "J'ai un doute sur ...". Je détesterais voir les anglophones natifs commencent à utiliser cette utilisation inappropriée du mot "doute".


6 Réponses :


20
votes

C'est parce que la sortie de printf () code> est tamponnée. Vous pouvez ajouter fflush (stdout); code> immédiatement après votre printf code> et il serait également imprimé.

Vous pourriez aussi faire ceci: p>

fprintf(stderr, "error string");


0 commentaires

5
votes

Si la défaillance de la segmentation se produit trop tôt après une impression, et que le tampon de sortie n'a pas été rincé, vous ne verrez pas l'effet du printf.


0 commentaires

5
votes

Sortie de la sortie de la mémoire de mise en œuvre de la plupart des implémentations de libc. Il suffit généralement d'appuyer Newline (\ n) à la chaîne de sortie pour la forcer à rincer le contenu des tampons.


3 commentaires

Cela ne sera pas suffisant. Vous devez appeler fflush ();


À moins que cela soit redirigé dans un fichier, auquel cas, il peut s'agir de la mise en mémoire tampon plus conventionnelle au lieu d'une tampon de ligne.


Ah bons points, j'ai supposé que la mise en mémoire tampon de ligne n'est pas bonne raison, merci.



3
votes

Vous pouvez affleurer le tampon de sortie juste après la gravure pour vous assurer qu'elle se produira avant une faute SEG. Par exemple. fflush (stdout)


0 commentaires

3
votes

Conseil aléatoire: Si vous essayez de déboguer des défauts de segmentation, assurez-vous d'essayer Valgrind . Cela facilite beaucoup plus facilement!


0 commentaires

0
votes

Vous avez reçu un certain nombre de réponses indiquant la mise en mémoire tampon du flux de sortie.

Pour le meilleur ou le pire, cela n'est nulle part près de la seule possibilité. Un défaut de segmentation signifie que le système d'exploitation a détecté que vous avez fait quelque chose de mal, généralement écrit en dehors de la mémoire allouée. Pour le meilleur ou le pire (principalement pire) faisant presque tout ce que dans une telle situation peut changer suffisamment de ce que le programme fait en interne pour empêcher le problème d'être détecté, du moins à l'époque / dans la situation où elle a été détecté précédemment.

Par exemple, le défaut de segment a peut-être été causé par écrit via un pointeur ininitialisé - qui est arrivé à contenir une certaine valeur (peut-être un petit entier) car une fonction que vous aviez appelée précédemment laissait cette valeur à la bonne place La pile que lorsque la fonction ultérieure a été appelée et utilisait cette même valeur qu'un pointeur, il (raisonnablement fiable) contenait une valeur que l'OS a détecté comme un endroit où vous n'étiez pas autorisé à écrire. Mettre en place un appel à Printf, cependant, pourrait signifier que vous laissez une valeur totalement différente à l'endroit sur la pile que vous utilisez sans l'initialisation. Vous écrivez toujours quelque part vous ne devriez pas, mais cela pourrait être quelque part que le système d'exploitation ne sait vous ne devriez pas écrire.


0 commentaires