C言語の範囲外の配列によって引き起こされる無限ループの理由の1つの詳細な説明

最初にこのコードを見てみましょう(VS開発環境):

#include <stdio.h>
int main()
{
    int i = 0;
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    for (i = 0; i <= 12; i++)
    {
        arr[i] = 0;
        printf("hello\n");
    }
    return 0;
}

VS開発環境での最終的な出力は何であるかを推測できますか?それは13のhelloまたはコンパイルエラーなどを出力していますか?忘れてください、答えが明らかになり、それは無限ループであり、無数のhelloが出力されます。なぜこれが起こっているのか、次に詳しく説明させてください〜

デバッグを通じて、arr [12]の値は常にiの値と同じであることがわかります。つまり、arr [12]が変更されると、iも変更され、その逆も同様です。

 

 これを見て、2つのアドレスが同じであるかどうかを推測することもできます。そうでない場合は、なぜ私を変更しますか?二人の住所を見てみると、本当に同じであることがわかりました!

なぜ?

 話す前に、このプログラムでは、i配列とarr配列がローカル変数であり、ローカル変数がスタック領域に格納されていることを最初に知っておく必要があります。

スタックの使用法は、最初に上位アドレスにスペースを割り当て、次にコードで変数が定義されている順序に従って下位アドレスにスペースを割り当てることです。配列のアドレスは、下付き文字。次の図は、上記の内容を簡単に表すことができます。

 図に示すように、iとarr配列の間のスペースが適切な場合、使用されるarr配列がiに逆方向にアクセスし、arr配列の特定の値が変更されるとiの値が変更される可能性があります。無限ループを引き起こすのは非常に簡単です。

最後に、上記のコードの実行結果はコンパイル環境の環境に厳密に依存しており、最終結果も異なる場合があることを付け加えておきます。たとえば、VC6.0では、iとarrは連続しており、間にスペースはありません。gccではiとarrの間にスペースがあります。VS2010、2013、2019などでは、上記の場合のように、iとarrの間に2つのスペースがあります。したがって、あらゆる種類の予測できない状況を回避するために、プログラムを作成するときは注意を払い、配列に範囲外にアクセスさせないようにすることをお勧めします~~

おすすめ

転載: blog.csdn.net/m0_63039919/article/details/121479389