私はprintfとは少し奇妙なことを発見しました。NULLポインタを使った基本的なprintfの動作
私は、次の
printf ("%s\n", (char *)NULL);
を行うと、私はセグメンテーション違反を得ます。
しかし、私はこれを行うとき:
printf (".%s\n", (char *)NULL);
を出力は以下でないと何のクラッシュ。
.(null)
なぜ行動の違いが分かりますか?
私はprintfとは少し奇妙なことを発見しました。NULLポインタを使った基本的なprintfの動作
私は、次の
printf ("%s\n", (char *)NULL);
を行うと、私はセグメンテーション違反を得ます。
しかし、私はこれを行うとき:
printf (".%s\n", (char *)NULL);
を出力は以下でないと何のクラッシュ。
.(null)
なぜ行動の違いが分かりますか?
生成されたアセンブリコードを見ると、printf ("%s\n",…)
がputs
の呼び出しでoptimized by the compilerになっていますが、他の形式の文字列はこのトリックには適していません。
printf
関数は、ヌルポインターを検出してクラッシュすることはありませんが、puts
関数はそうではありません。
区別はありません。%s
の場合、NULLポインタをprintf
に渡すことは未定義の動作です。特定のコンパイルプラットフォームで2度目の運があったとしても、それはこれまでどおりです。
未定義の動作には* anything *を含めることができます。 – EOF
[非常に簡単な説明については、この回答を参照してください(これは重複していると思います)](http://stackoverflow.com/a/11589443/1287251)。短い答え: 'printf("%s \ n "、...)'は 'NULL 'にセグメンテーションする' puts'に変換されますが、 'printf("。%s \ n "、...)'は'NULL'を'(null) 'に変換する実際の' printf'関数です。 – Cornstalks
奇妙なことや悪いことをやめ、奇妙なことが起こるのをやめます。 –