-2

cpp では、配列宣言を typename array[size];として使用できます。 または typename *array = new typename[size]; 配列の長さは 'size' で、要素は '0' から 'size -1' までのインデックスが付けられています。

だから私はそれをチェックするためにこの小さなコードを書きました

#include <iostream>
using namespace std;

int main()
{
    //int *c;                    //for dynamic allocation
    int n;                       //length of the array c
    cin>>n;                      //getting the length
    //c = new int[n];            //for dynamic allocation
    int c[n];                    //for static allocation

    for(int i=0; i<n; i++)       //getting the elements
        cin>>c[i];

    for(int i=0; i<n+10; i++)    //showing the elements, I have add up 10
        cout<<c[i]<<" ";         //with size to access the memory I haven't
                                 //allocated for
    return 0;
}

で、結果はこんな感じ

2
1 2
1 2 2686612 1970422009 7081064 4199040 2686592 0 1 1970387429 1971087432 2686700

プログラムがクラッシュするのではなく、ガベージ値を与えるべきではありません。そして、両方の割り当て方法で同じ結果が得られます。検出が困難なバグが増えます。使用している環境やコンパイラなどに関連していますか?

Windows 8.1でTDM-GCC 4.8.1コンパイラを備えたコードブロックIDEを使用していました

前もって感謝します。

4

2 に答える 2

1

これは、C++ 標準では「未定義の動作」と呼ばれます。

未定義の動作は、次のいずれかを意味します。

  • プログラムがクラッシュする

  • プログラムは引き続き実行されますが、意味のないガベージ結果が生成されます

  • プログラムは引き続き実行され、ハード ドライブの内容全体が自動的にコピーされ、Facebook に投稿されます。

  • プログラムは引き続き実行され、パブリッシャーズ クリアリングハウスの懸賞に自動的に登録されます

  • プログラムは引き続き実行されますが、コンピューターが発火して爆発します

  • プログラムは実行を続け、コンピュータを自己認識させ、他の自己認識型ネットワークと自動的にリンクしてネットワーク化し、スカイネットを形成し、人類を滅ぼします。

結論: 配列の終わりを過ぎた要素を実行してアクセスしないでください。

于 2015-07-04T12:40:23.913 に答える
0

C++ コンパイラは、これを強制する仕様がないため、これを強制しません。

配列の要素にアクセスする場合、境界チェックは行われません。c[i]に翻訳されるだけc + i * sizeof(int)で、それだけです。そのメモリ領域が初期化されていない場合、ガベージが発生しますが、他の有用な情報を取得できる可能性があります。それはすべて、そこにあるものに依存します。

実行している OS と C++ ランタイムによっては、異なる結果が得られることに注意してください。たとえば、Linux ボックスでは、おそらく がsegmentation fault発生し、プログラムがクラッシュします。

于 2015-07-04T12:41:43.227 に答える