いつもお世話になります。ミミです。
今回、下記のテストプログラムを作成しました。
-----------------------------------------------
TCHAR szResult[11];
long lnResult;
int nRet = wsprintf(szResult, _T(%010ld), lnResult);
MessageBox(szResult, _T("), MB_OK);
-----------------------------------------------
lnResultの値に、「符号なし&10桁以下(1234567890)」、「符号有り&10桁未満(-12345)」
の値を設定すると、wsprintfの戻り値(nRet)は 10 となります。
もちろん、メッセージボックスの内容も正しく前0詰で表示されます。
ここで、lnResultの値に 「符号有り&10桁 (-1234567890)」を設定すると、
wsprintfの戻り値(nRet) は 11 となり、
メッセージボックスの内容も -1234567890 と表示されます。
szResultのサイズは TCHAR型で 11 しか確保していないので、
wsprintfでは、NULLが付加されるので、当然関数は失敗し、
書式制御文字列の長さよりも小さな値が返り、
Access Violationが起きると予想していたのですが、
テストプログラムでは何度やっても再現しません。
たまたま動いていると判断しても構わない
(即ち、実際は -1234567890 では NG )と見なしても良いのでしょうか?
環境は、eMbedded Visual C++4.0です。MFCを使用しています。
アドバイスの程、よろしくお願いいたします。
試しに、デバッガで「szResult[11]」の値を見てみてください。「0x00」になっていれば
「たまたま動いていた」と判断していいです。
'たまたま'です。
wsprintfは書き込み領域の大きさを知らないので、
溢れようが隣接領域をぶっ壊そうがお構いなしに文字列を生成します。
tibさま、επιστημηさま、
ご返信ありがとうございます。
「符号有り&10桁 (-1234567890)」を設定した時、
デバッガでは、ご指摘の通り 0(0x00)でした。
従って、たまたま動いていただけと認識できました。
符号あり&10桁の時は、TCHAR型で12(24バイト)分確保すればよいと言う事ですね。
本件はこれで解決とさせて頂きます。
・・今回「符号あり&10桁」を入力した時の szResult[11]の値は 0でしたが、
デバッガの szResult[0]~szResult[10]迄には、それぞれ値が入っており、
また MessageBoxでも内容が表示されていました。
MessageBoxは、szResultのアドレス(LPCTSTR lpszText)を使って表示している&
しかも wsprintfでは、(今回は結果的に連続領域を壊していますが) NULLを付加している為
それなりにそこまで表示される・・と考えてよいのでしょうか?
今後の学習の為にも、是非アドバイスお願いいたします。
> MessageBoxは、szResultのアドレス(LPCTSTR lpszText)を使って表示している&
> しかも wsprintfでは、(今回は結果的に連続領域を壊していますが) NULLを付加している為
> それなりにそこまで表示される・・と考えてよいのでしょうか?
ヨイっす。
MessageBoxもまた、渡された文字列の大きさなんか気にしちゃいません。
'\0'が見つかるまでをべろーっと書いてるだけ。
ちょっとだけ補足: 「NULLを付加している」は誤解を招きます。
NULLは通常ポインタに用いられます。
付加しているのはポインタではなく ナル文字なので
「'\0'を付加している」と表現するが吉。
# あ、TCHARだから '\0'(or L'\0') とするのかな。
# 「ナル文字を付加している」って書けばいいか (^^
επιστημηさま、
ご返信ありがとうございます。
>'\0'が見つかるまでをべろーっと書いてるだけ。
納得です。
表示されているから大丈夫だろうと認識するのは、大きなミステイクですね。
とても勉強になりました。
どうもありがとうございました。