C'est "sûr" dans un sens, et dangereux dans un autre. Il n'est pas sûr d'ajouter des printfs de débogage et, pour la même raison, d'ajouter du code pour modifier la mise en mémoire tampon de stdio, dans le sens où c'est un cauchemar de maintenance. Ce que vous faites n'est PAS une bonne technique de débogage. Si votre programme reçoit une erreur de segmentation, vous devez simplement examiner le vidage mémoire pour voir ce qui s'est passé. Si cela ne suffit pas, exécutez le programme dans un débogueur et parcourez-le pour suivre l'action. Cela semble difficile, mais c'est vraiment très simple et c'est une compétence importante à avoir. Voici un exemple :
$ gcc -o segfault -g segfault.c # compile with -g to get debugging symbols $ ulimit -c unlimited # allow core dumps to be written $ ./segfault # run the program Segmentation fault (core dumped) $ gdb -q segfault /cores/core.3632 # On linux, the core dump will exist in # whatever directory was current for the # process at the time it crashed. Usually # this is the directory from which you ran # the program. Reading symbols for shared libraries .. done Reading symbols for shared libraries . done Reading symbols for shared libraries .. done #0 0x0000000100000f3c in main () at segfault.c:5 5 return *x; <--- Oh, my, the segfault occured at line 5 (gdb) print x <--- And it's because the program dereferenced $1 = (int *) 0x0 ... a NULL pointer.
Eh bien. Vous vous trompez. Précisément pour cette raison, stderr n'est pas mis en mémoire tampon par défaut.
EDIT :Aussi, comme suggestion générale, essayez d'utiliser les points d'arrêt du débogueur au lieu de printf
s. Rend la vie beaucoup plus facile.
Un moyen possible pourrait être d'avoir un bool dodebug
drapeau global et définir une macro comme par exemple
#ifdef NDEBUG
#define debugprintf(Fmt,...) do{} while(0)
#else
#define debugprintf(Fmt,...) do {if (dodebug) { \
printf("%s:%d " Fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \
fflush(stdout); }} while(0)
#endif
Ensuite, dans votre code, ayez quelques
debugprintf("here i=%d", i);
Bien sûr, vous pourriez, dans la macro ci-dessus, faire fprintf
à la place... Remarquez le fflush
et la nouvelle ligne ajoutée au format.
La désactivation de la mise en mémoire tampon devrait probablement être évitée pour des raisons de performances.
pourquoi tous les flux sont mis en mémoire tampon par défaut
Ils sont mis en mémoire tampon pour des raisons de performances. La bibliothèque s'efforce d'éviter de faire l'appel système car cela prend du temps. Et tous ne sont pas mis en mémoire tampon par défaut. Par exemple stderr
est habituellement sans tampon et stdout
est mis en mémoire tampon uniquement lorsqu'il fait référence à un tty.
alors est-ce sûr de le faire ?
Il est prudent de désactiver la mise en mémoire tampon, mais je dois dire que ce n'est pas la meilleure technique de débogage.