- ベストアンサー
文字列のprint文
以下の様なNULLストップされていない文字列のprint文は問題があるのでしょうか #include <stdio.h> main() { char *x; x = malloc( 2 ); x[0]= '0'; x[1]= '1'; printf("x(.2s):%.2s\n", x ); } bcheckで確認すると以下の様なメッセージが出力されます。 ----------------------------------------------- }<rtc>非割り当て領域からの読み取り (rua): 1 バイト読み取り を アドレス 0x20d8a で しようとしました それは 0x20d88 で始まる大きさ 2 バイト のヒープブロックの直後 です このブロックは以下から割り当てられました: [1] main() at 0x10834 エラーの位置: =>[1] _doprnt(0x20b28, 0xfd51aad6, 0x0, 0x0, 0x40, 0xf71bd761)、アドレス 0xfd507760 [2] printf(0x20b28, 0x20d88, 0x5, 0x4, 0x0, 0x1)、アドレス 0xfd508720 [3] main(0x1, 0xffbef7fc, 0xffbef804, 0x20800, 0x0, 0x0)、アドレス 0x1085c ----------------------------------------------- 因みにpurifyではエラーとしては認識しませんでした。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
実際エラーになるようなプログラムがあるなら 問題あるでしょうね。 #1でも言われているように、printfの実装によると思います。 %sは、もともと0エンド文字列をお想定していますからそこに、0エンドしてない文字列を指定する方が(指定文字数がEOS:0まで達していないとしても)おかしいとも言えると思います。(つまり実装者は、EOSがあると想定しても良いプログラミングをしているので) %cを使った方が意味的にもいいと思いますが。
その他の回答 (3)
- qa_goo
- ベストアンサー率60% (6/10)
ふむ、処理系は何ですか? "%2s" で3文字にしたら "012" と 表示されてるのですね。 おそらく偶然にも '2' の後ろが NULL になってるんでしょう。 そうでないと printf には 3文字なんて分からないはず。 "%2s" なら NULL まで探してるのは確実ですよ。 実装というより printf の仕様的に。 "%2.2s" でもエラーになるのは ちょっと不思議ですね。 これは printf の実装の違いなのかな。 ちなみに MS の VC++ 系の場合は、 Debug と Release で確保領域の初期化が 異なるので結果も異なりますけど・・・。
補足
ご返答ありがとうございます。 マシンはsolaris8です。 因みに"%2s"ではなく"%.2s"です。 ライブラリにUBCLIBがリンクされない状態のビルドではbcheckによるエラーは発生しなくなりました。なぜだか不明です。
- qa_goo
- ベストアンサー率60% (6/10)
そもそも、書式 %2s では 2文字で切り捨てる意味にはなりませんよ。 printf("%2s", "ABCD") とやれば "ABCD" と表示されるはずです。 NULL まで探すのでアクセス違反になります。 2文字で制限するには "%2.2s" かな。 この場合、2文字までしか読まないはずなので アクセス違反にもならないと思いますが。
お礼
回答ありがとうございます。 "%2.2s"で実行してみましたが、bcheckで同様に領域外読込みのエラーになってしまいました。 因みに main() { char *x; x = (char * )malloc( 3 ); x[0]= '0'; x[1]= '1'; x[2]= '2'; printf("x(.2s):%.2s\n", x ); } の様に0エンドではないが、1文字多いとbcheckではエラーになりませんでした。 どうやらprintfの実装はNULLまでは探していないようです。
- JaritenCat
- ベストアンサー率37% (122/322)
%.2s で桁数を指定しているので問題なさそうに見えますが、結局printfの内部処理がどうなっているかによるので、問題がないとは言えません。 自作のprintfを使うのであれば問題ないように作れるでしょうが、移植性を考えるとまずいですよね。。。
補足
早速の返答ありがとうございます。おっしゃる通りです。printfしだいですから。
お礼
回答ありがとうございます。エラーとはメモリーチェックのエラーのことですね。 確かに想定外の使い方ですから問題です。 %cに切り替えるか、0エンドに置き換えて使うようにします。