5

アプリケーションの出力(下)は次のとおりです。

要素インデックス番号:0要素コンテンツ:22
要素インデックス番号:1要素コンテンツ:22
要素インデックス番号:2要素コンテンツ:22
要素インデックス番号:3要素コンテンツ:22
要素インデックス番号:4要素コンテンツ:22
要素インデックス番号:22要素の内容:134513712

5〜21のラベルが付いたインデックス要素が欠落しているのはなぜですか?配列の境界がオーバーフローしたためにこのコードがセグメンテーション違反になる可能性があることを理解しています。そのように設計されています。このコードがなぜ悪いのか、特定のインデックスがスキップされる理由には興味がありません。

#include <stdio.h>
int main(){

    int array[5];

    int i;
    for(i=0; i<10; ++i) {
        array[i] = 22;
        printf("Element index number: %d Element contents: %d\n", i, array[i]);
    }
    return 0;
}
4

5 に答える 5

9

割り当てられたメモリをオーバーフローさせると、「未定義の領域」になります。おそらく、配列の書き込みは、「i」がスタックのどこに格納されているかに書き込まれます。

JavaやC#のような言語とは異なり、Cは実行時の境界チェックを行わないため、配列、文​​字列、またはマロックされたメモリをオーバーランしたときに、有用な処理(segfaultなど)が保証されないことに注意してください。何かをすることは保証されていません。クラッシュしたり、走り続けたり、悪魔が鼻から飛び出したりする可能性があります

于 2009-06-01T18:18:47.940 に答える
7

何が起こっているのかというと、array [5]に書き込むときは、iに書き込んでいるということです。これらはメモリ内のスタックに隣接しているため、これが期待できる動作です。

このように考えてください、あなたはで5つの要素を持つ配列を作りました

int array[5];

実際には、配列は単なるアドレスです。[]内の数字は、そのアドレスからどれだけ離れてアクセスできるかを指定します。それで:

  • array[0]アドレス"array"を過ぎたメモリ内の0int
  • array[1]はアドレス"array"..を過ぎたメモリ内の1intです。
  • array [4]は、アドレス「array」(配列用に予約した最後のint)を過ぎたメモリ内の4つのintです。

したがって、次のようになります。

  • array [5]は、アドレス「array」を過ぎたメモリ内の5intです。

Cには境界チェックが自動的に行われないため、自分のメモリを上書きできます。スタック内のarray[5]の後に「i」を配置しました。おそらくarray[5]はiです。

array [5]またはiを22に設定したので、iは22になります。iが22になったので、array[i]への次のルックアップは実際にはarray[22]です。これにより、メモリ内のその場所にあるジャンクがすべて取得されます。運が良ければ、クラッシュします。

于 2009-06-01T18:19:00.497 に答える
2

@Dougにはそれがありますが、少し拡張してみましょう。

自動変数としてarray[5]とiがあるので、それらはエントリ時にスタックに割り当てられるので、array [0]、array [1]、... array [4]、そしてiの6つのセルを割り当てます。 。

iを5に設定すると、array[i]はiを含むスタック上のセルを指します。次に、22を割り当てました。印刷したとおり、i=22になります。

次に、配列[i]または配列[22]を取得します。これは、stckの終わりから下にあります。そこにあるランダムな値はたまたまその大きな数です。

于 2009-06-01T18:26:12.343 に答える
0

ほとんどの場合、ローカル変数「i」のストレージはスタックの「array」の直後にあるため、&array [5] ==&iです。つまり、22をarray[5]に割り当てるときに22を「i」に割り当てます。

于 2009-06-01T18:20:43.647 に答える
-1

5つのintの配列を宣言しましたが、forループは値を10のエントリに書き込みます。

変化する

int array[5];

int array[10];
于 2009-06-01T18:23:43.453 に答える