2012-04-29 11 views
-1
int main() 
{ 
    int i,j,k; 
    i=1;j=2;k=3; 
    int *p =&k; 
    *(p-1)=0; 
    printf("%d%d%d",i,j,k); 
    getch(); 
} 

出力は、プログラムが未定義の挙動を示す1 2 3なぜこのプログラムは実行時にエラーを出さないのですか?

+1

まず、ランタイムエラーが発生するのはなぜですか? –

+0

メモリアクセス違反の可能性があります。 – Ashok

+0

なぜそれはすべきだと思いますか? pはスタック上のkを指し、p-1はスタック上のkの前の1つの整数を指します。アクセス違反は必要ありません。しかし、それは危険で未定義の行動です。 – ssteinberg

答えて

3

、あなたがやっているポインタ算術演算が無効です。

実際に配列を指すポインタ上でのみポインタ演算を行うことができます。また、加算または減算の結果は配列内を指していなければなりません(逆参照する予定がない場合は、 。

何かが起こる可能性があるので、コンパイラはそのコードのように感じるコードを生成できます。

+0

私はこのコードを試しました。なぜなら、int i; float * p =(float *)&i; * p = 100.00; printf( "%d"、i);実行時エラーが発生しません。だから私は上記のコードの予期しない動作を期待する必要がありますか? – Ashok

+0

これも無効なコードです。エイリアスのルールに違反しています。 http://stackoverflow.com/questions/98340/what-are-the-common-undefined-unspecified-behavior-for-c-that-you-run-into – Mat

2

p-1を割り当てた後には&kを参照することはできません。これは無効なポインタであり、使用する動作は未定義です。

+0

まあ、実際にあなたはどんな住所も参照することが許されています。あなたが行ったときに何が起こるかは不明です。だからあなたはすべきではありません。それは良い点ですが、OPが求めているものかもしれません。それはJavaではありません。 – joshp

+0

実際には、この規格によれば、それをまったく使用することはできません。それを別の変数に代入することさえせず、そのようなアクションは未定義の動作を引き起こします。 – MByD

+0

私はあなたの知識に従います。私が最も多くしたときは、標準はなかった。私は彼のコンパイラが彼にそれをさせていると思う。それは私が許すことによって意味するものです。あなたが何を呼んでもそれをするのは悪いことです。 – joshp

0

ランタイムエラーは、ある種の保護されたメモリや、後である計算(0)で除数になる場所など、そのエラーを発生させるものにヒットした場合にのみ発生します。

関連する問題