int main(void)
{
int i;
int array[5];
for (i = 0; i <= 20; i++)
array[i] = 0;
return 0;
}
上記のコードが無限ループに陥るのはなぜですか?
int main(void)
{
int i;
int array[5];
for (i = 0; i <= 20; i++)
array[i] = 0;
return 0;
}
上記のコードが無限ループに陥るのはなぜですか?
5 つの要素を持つ配列を宣言しますが、それに 21 の要素を書き込みます。配列の末尾を超えて書き込むと、未定義の動作が発生します。あなたの場合、ループ カウンターに書き込みi
、おそらく割り当て時に 0 にリセットしますarray[5]
。
プログラムを修正したい場合は、正しい要素数に書き込むようにループを変更してください
int num_elems = sizeof(array) / sizeof(array[0]);
for (i = 0; i < num_elems ; i++)
許可されているメモリを超えて上書きすることにより、未定義の動作を呼び出しています。だから何でも起こり得る。
ほとんどの場合、ループ カウンターを上書きしています。
指定されたコードで何が起こっているかを次に示します。
#include<stdio.h>
#include<string.h>
int main(void)
{
int i;
int array[5];
for (i = 0; i <= 20; i++)
{
printf("%p %p \n",&i,&array[i]);
printf("the value of i is %d \n",i);
sleep(1);
array[i] = 0;
printf("i may be modified here lets see what i is %d \n", i);
}
return 0;
}
私のスタックメモリでは、アドレスの場所を次のように取得しました
i
場所 0xbfd1048c アドレスに保存されます
array
場所0xbfd10478アドレスに保存されます
i
ある時点で各ループの値をインクリメントしているため、のアドレスはのアドレスarray[i]
と同等ですi
(ポインターの逆参照のみ)
したがって、保存してarray[i]
いるのはi
のインスタンスアドレスにi
他ならないため、前述のようにインスタンスの値を0に上書きしarray[i] = 0
てi=0
いるため、条件i<=20
は常に成功します。
ここで、なぜメモリがそのように割り当てられるのかという大きな疑問があります。
これは、実行時およびカーネルへのリソースの可用性に基づいて決定されます。
そのため、配列の限界にとどまらなければなりません。
問題は、配列の境界の外側にある要素にアクセスしようとしたときです。これは、5 の大きさしかありませんが、21 の大きさのループ内にあります。
int main(void)
{
int i;
int array[5];
for (i = 0; i < 5; i++)
array[i] = 0;
return 0;
}
無限ループ状態は見当たりませんが、5 つの「スロット」を持つ配列に最大 20 の値を設定していますか???