変数 a は関数 fun() に対してローカルであり、制御が関数 fun() から戻ると存在しなくなるはずなのに、なぜ printf は 7 を出力するのですか。
ここにcコードがあります
#include<stdio.h>
main()
{
int *fun();
int *c=fun();
printf("%d",*c);
getch();
}
int *fun()
{
int a=7;
return(&a);
}
出力 : 7
変数 a は関数 fun() に対してローカルであり、制御が関数 fun() から戻ると存在しなくなるはずなのに、なぜ printf は 7 を出力するのですか。
ここにcコードがあります
#include<stdio.h>
main()
{
int *fun();
int *c=fun();
printf("%d",*c);
getch();
}
int *fun()
{
int a=7;
return(&a);
}
出力 : 7
これは、変数が存在しなくなったとしても、それがあったメモリの場所がまだ別の目的で使用されていないためです。intしたがって、ポインターは、ビットが値 7 を含むメモリ位置を指し続けます。
しかし、これは間違いなく未定義の動作です。それに頼ってはいけません。
言語イディオムとハードウェアの物理的操作には違いがあります。「C」の言葉で言えば、はい、あなたの変数はもうアクセスされるべきではありませんが、物理的に変数aはプログラムのスタックに割り当てられており、関数が戻るたびに消去されることはありません(時間がかかりすぎるでしょう)。まだそれを読むことができます。
とにかく、他の関数呼び出しがこのデータを消去する可能性があるため、これはお勧めしません。
fun() が戻ると、フレーム ポインターは再び main() フレームを指すように設定されます。ポインター c はメモリ内のアドレスを指していました。fun() は既に返されているため、アドレスの内容はわかりませんが、アドレスに他に何も書き込まれていない場合は、以前の変数 a のままである可能性があります。C 標準では、関数が戻るときにフレーム ポインターを移動するだけです。
場所に格納されている値を表示する*cを印刷しているためだと思います。つまり、&aです。cを印刷してみると、7のアドレスが得られます。
これは、アドレスがすでに変数cに渡されており、メモリアドレスを関数の外部でも読み取ることができるためです。