2016-04-07 5 views
-2

私は自動変数の作業を研究しています。私は、それが宣言されているブロックまたは関数内でのみアクセス可能で、その存続時間は同じ関数またはブロック内にあることを知っています。だから次のコードをチェックしようとしています。ヘッダファイルのC言語でのスコープ外の自動変数の使用

/宣言/

void testfn(void); 
int *p; 
int main(void) 
{ 
    testfn(); 
    print("%d\n",*p); 
    return 0; 
} 

void testfn(void) 
{ 
    int x=444; 
    p=&x; 
} 

出力は、 - 444

場合testfn()は私は思っています。終了すると、変数xは破棄されます。次に、ポインタ(* p)が444をどのように表示するかをメイン関数で示します。 これはどのように動作しますか?何か不足している場合。 疑いを明確にしてください。

おかげ

+0

定義されていない動作... – dandan78

+0

これは未定義の動作のものです。実際には動作していない場合は、期待される動作のように見えます。残念ながら、定義されておらず、間違った動作が定義されていません。 –

+1

アドレスは、関数がアクティブであったときと同じ値を持ちますが、それが指すメモリはその関数に割り当てられなくなりました。しかし、これはすべて本当に時間の無駄です。あなたが勉強しようとしていることは分かっていますが、これはあなたがここに投稿するべきものではありません。 –

答えて

1

以前にまだ上書きされていない変数xのために予約されたメモリ位置。しかし、それはいつでも可能性があります。だからあなたのコードは未定義の動作につながります。

次の例では、以前に変数xに予約されていたメモリの場所は、変数yに割り当てられた値で上書きされます。ポインタpはまだその場所を指しているので、*pは、この新しい値に評価されます:それは偶然の一致は、元の値がまだ残っていること

#include <stdio.h> 

int *p; 

void test1(void) { 
    int x = 444; 
    p = &x; 
} 

void test2() { 
    int y = 15; 
} 

int main(void) { 
    test1(); 
    test2(); 
    printf("%d\n",*p); 
    return 0; 
} 
0

です。別のコンパイラや別のコンパイル設定では、他の値をとることも、プログラムがクラッシュする可能性もあります。

testfnprintf関数の間で、ローカル変数で何かを行う他の関数を呼び出すと、444の値がそれ以上取得されないことがあります。しかし、これはちょうど、再び、偶然です。

0

pは、xが格納されたスタックを指している。メモリの場所が何かのために使用されていない場合は、おそらく444が得られます。

pを印刷する前に、別の関数の呼び出しを挿入し、何が起こるか見てみてください:私のマシン上で

#include <stdio.h> 
#include <math.h> 

void foo() { 
    int y=123; 
} 

void testfn(void); 
int *p; 
int main(void) 
{ 
    testfn(); 
    foo(); 
    printf("%d\n",*p); 
    return 0; 
} 

void testfn(void) 
{ 
    int x=444; 
    p=&x; 
} 

を、出力は以下のようになります。未定義の動作のコード結果以来

123 

、これを別のプラットフォームで試してみると、結果が異なる可能性があります。しかし、未定義の振る舞いが奇妙なバグにつながることがわかります。

0

値がまだ残っているという事実は、まだ何もそれを上書きしていないので完全に偶然(保証されていない)です。

これにはカウントできません。失敗する可能性があります。ゴミが印刷されたり、プログラムやPCがクラッシュすることがあります。

これは使用しないでください。未定義の動作とみなされます。