次のコードでは、
#include <stdio.h>
int main()
{
int i = 5;
scanf("%s", &i);
printf("%d\n", i);
return 0;
}
のアドレスに格納されている入力文字列を取得しますi
。変数を印刷しようとすると、i
いくつかの数値が得られます。
入力例:
hello
出力:
1819043176
これは何の数字で、正確には何が起こっているのでしょうか?
このプログラムは、ユーザーから読み取った文字列を、変数 i が占有するメモリに書き込み、それを過ぎます。これは未定義の動作であるため、何かが起こる可能性があります。
実際に起こっていることは、あなたのマシンint
のサイズは 4char
秒で、文字「地獄」を ASCII に変換し、CPU のバイト オーダーの数値として解釈すると、1819043176 という数値になるということです。文字列、文字 o および終端のヌル文字は、マシン上の i が保存されている場所の末尾を超えています。それで、これscanf
は何ですか:
h e l l o \0
|68 65 6c 6c|6f 00 ...
| i|memory past i
これをリトルエンディアンのマシンで実行しているように見えるため、バイトが int に格納されると、数値または10進68 65 6c 6c
数として解釈されます。0x6c6c6568
1819043176
サイズが異なる場合int
、またはマシンが別の文字セット (ASCII ではなく EBCDIC など) を使用している場合、または CPU がビッグエンディアンのバイト順を使用している場合、またはプログラムがメモリ書き込みがバウンド チェックされている環境で実行されている場合は、異なる結果が得られるか、プログラムがクラッシュします。要するに、未定義の動作です。