質問

これが素人の質問だったらごめんなさい:( 。

C コードの一部。

int array[5];
int cnt;

for(cnt = 0; cnt <= 10; cnt+=1)
{
      array[cnt] = cnt;
}

エラーが出るはずですよね?いいえ!正常に動作します!しかし、それはなぜでしょうか?-最初の行で-倍のサイズ(11)を超える配列が定義されているようです。後から array[5 to 10] にアクセスすることもできます。そしてそれは私を混乱させます。array[4 以下] を定義すると機能しなくなります...

前もって感謝します。

役に立ちましたか?

解決

特定のコンパイラやコンピュータでは動作する可能性がありますが、それを当てにすべきではありません。

C 言語仕様に従ったコードの動作は次のとおりです。 未定義. 。これは、期待通りの動作をするか、コンピュータがクラッシュするか、または問題が発生する可能性があることを意味します。 悪魔があなたの鼻から飛び出す.

Java や C# などの高水準言語とは異なり、C はユーザーを信頼し、配列の境界に対して明示的なチェックを実行しません。あなたには責任があり、アレイの境界の外に出てはいけないと考えられています。

他のヒント

「作品」のあなたの定義は。

「まだクラッシュしていない」と同義である場合は、

この唯一の「作品」

あなたが見ていると、あなたは無効なインデックスを持つ配列にアクセスすることにより生じたの未定義の動作のです。未定義の動作は何が正しく動作するように表示されて、あなたのプログラムを含む、起こる可能性があることを意味します。

"がこの理由は何でしょうか?"

この方法Cです。

配列の境界のチェックです。

これに"法のC"

私はこのすべてが実際に定義されていないことを指摘したいです。 両方の変数がスタック上に配置されているので、あなたの例では、この特定の例では「働きます」。それは、CNTのアドレスであるだけで配列の最後を下回っています。 CNTは、CNT == 5に到達すると ステートメント配列[CNT = CNT。 CNTのアドレスが横たわっていた配列にちょうどそれの後に専用のメモリに書き込みません。それはあなたのカウンターを変更していないだけで幸運です。 CNTは> 5、ゴミ箱へのメモリがありません、それは単に「スタックボイド」(適切な言葉を知らない)に書き込まれます。

とき

別の例では、これを説明する:

int main(int ac,char **av)
{
    int a[5];
    int cnt;
    int cnt2=3;

    for(cnt=0;cnt<7;cnt++) {
        a[cnt]=cnt;
        printf("%d %d %d\n", a[cnt], cnt, cnt2);
    }
}

出力:

0 0 3
1 1 3
2 2 3
3 3 3
4 4 3
5 5 5
6 6 5

ループの最後の2つの書き込み[]は後にスタックデータを上書きし、非常に混乱エラーを生じ得ます。この場合、CNT2がゴミ箱に移動されます。

Cでの配列は、実行時にチェックされません。言い換えれば、あなたは、サイズNの配列を「定義」することができますし、幸せにバインドされた配列の最後のオフにアクセスします。あなたは、配列の終わりをオフに行く場合は、スタック(またはヒープ)上のどこかのメモリをゴミ箱ます。

あなたがどこかのメモリをゴミ箱たら

、あなたのプログラムがクラッシュする可能性があります。彼らは遠く離れて、あなたが実際には配列の最後をオーバーランどこからクラッシュする可能性がありますので、これらのクラッシュは、追跡するのは難しいことができます。

一般的に、あなたがCで配列を宣言するとき、それは配列のサイズをマークするために、一定またはの#defineのいくつかの並べ替えを使用するのが最善です。

#define MAX_ELEMENTS 10
int array[MAX_ELEMENTS];
int cnt;
for(cnt = 0; cnt < MAX_ELEMENTS; cnt+=1) {
   array[cnt] = cnt;
}
あなたは、配列の割り当てにMAX_ELEMENTS過ぎて行く場合は、

、あなたはCNTの値が上書きされることがあります。あなたは、いくつかの他の変数が上書きされることがあります。すべてのコンパイラとコードの構造に依存します。また、ループの中に<記号の使用を注意してください。あなたはより少なくよりとより少なくよりまたは等しく-にないを使用してチェックする必要がありますので、Cの配列は0ベースにしています。

Cでの配列の境界は、の必要はないの実行時にチェックされます。彼らが選択するか、いない場合は、標準ではそうして自由に実装を残し - それは、の定義されていないものの一部です。脂肪のポインタと実装上のサンプルは、実際に何らかのエラーが発生する可能性があります。

あなたは、配列の終わりをオフに実行すると、

は、ソフトウェアが期待されていないこと、メモリを上書きし、ヒープが破損しています。あなたのソフトウェアを実行し続ける可能性があり、それは非常に不安定になります!

スタックメモリがパックされた方法によって異なります。また、それは喜んでそれらの値を上書きします、さらにはそれらを読んで、しかし、ほとんどの場合、あなたがスタックを破損されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top