2017-02-01 9 views
0

以下のコードでは、temp変数に配列0のインデックスを格納しようとしています。このコード行では、a[i-1]=a[i]-a[i-1]; i = 0の場合、a [i-1]は[-1]になります。変数の値の変更

  1. なぜコンパイラはエラーを起こさないのですか?
  2. なぜ、i = 0でtempが他の場所で使用されていない場合でも、temp変数の値は影響を受け、最初の反復後にゼロになります。たとえば、

私のように入力を与えたとき、:

3 1 2 3 

出力:

i:0 
a[0]: 1 
TEMP: 1 
TEMP: 0 
TEMP: 0 

TEMP: 0 

実際に何が起きているのでしょうか?コンパイラの動作を参照して説明してください。私は条件を入れれば、if(i!=0) a[i-1]=a[i]-a[i-1];というコードが正常に動作することを知っています。しかし、なぜ私はこのシナリオで起こっているのか知りたい。なぜコンパイラがエラーを与えていない

#include<bits/stdc++.h> 

using namespace std; 

int main() 
{ 
    int a[10],i,n,temp; 
    cin>>n; 
    for(i=0;i<n;i++){ 
     cin>>a[i]; 
     if(i==0){ 
      temp=a[i]; 
      cout<<"i: "<<i<<endl; 
      cout<<"a[0]: "<<a[i]<<endl; 
     } 
     cout<<"TEMP: "<<temp<<endl; 
     a[i-1]=a[i]-a[i-1]; 
    } 
    cout<<endl<<"TEMP: "<<temp; 
} 
+3

[未定義の動作](http://en.cppreference.com/w/cpp/language/ub) – 101010

+0

[i-1]は最初の繰り返しで範囲外です –

答えて

1

コンパイラがエラーを与えるために必要とされていません。範囲外の配列にアクセスすると、未定義の動作が発生します。実行時に配列が範囲外にアクセスされることは明らかです(プログラムの作成者がプログラムを実行する前にそれをキャッチしていないため、あまりにも明白ではないかもしれませんが)。コンパイラは一般的なバグを探すために実行パスをチェックします。

一時変数の値が影響されない、それは値のみ割り当てられているが、I = 0とTEMPが他の場所に使用されていない場合、最初の反復の後にゼロになる理由
  • プログラムの動作が定義されていないためです。


    すべての可能な方法で動作させるとプログラムは、いくつかのように動作理由を分析するために、通常は無意味です。しかし、この場合、最も可能性が高いと思われます。境界から書き出すと、配列の一部ではないメモリが上書きされます。他の変数は、配列の一部ではないメモリ内に位置していてもよい。したがって、配列の一部ではないメモリを上書きすると、他の変数の値が破損する可能性があります。それがあなたが観察したものです。

    0
    1. コンパイラでエラーが発生しないのはなぜですか?すでに述べたように、@のuser2079303として

    、このようなエラーが見つけるため、コンパイラはあまりにも困難です。このような複雑なエラーを見つけるためのツールとして、静的および動的コードアナライザがあります。あなたはVS 2015からデフォルトの静的コードアナライザを使用した場合、それは次の警告を与える:

    Severity Code Description 
    Warning C4701 potentially uninitialized local variable 'temp' used 
    Warning C6385 Reading invalid data from 'a': the readable size is '40' bytes, but '-4' bytes may be read. 
    Warning C6386 Buffer overrun while writing to 'a': the writable size is '40' bytes, but '-4' bytes might be written. 
    Warning C6001 Using uninitialized memory 'temp'. 
    

    、あなたのプロジェクトのための余分な安全性が必要な場合は、すべての(またはほとんどすべて)有効にすることを検討可能な警告と実行コード解析定期的に。

    関連する問題