例コード:範囲外の変数へのポインタを保持することは安全ですか?
#include <stdio.h>
int main(){
int *p;
{
int v = 1;
p = &v;
}
printf("%d\n", *p);
return 0;
}
このコードは正常に動作しますが、私はVのアドレスが保存されるという保証はありますかはわかりません。
例コード:範囲外の変数へのポインタを保持することは安全ですか?
#include <stdio.h>
int main(){
int *p;
{
int v = 1;
p = &v;
}
printf("%d\n", *p);
return 0;
}
このコードは正常に動作しますが、私はVのアドレスが保存されるという保証はありますかはわかりません。
保証はありません。
v
が範囲外になると、ポインタを使用しても何も実行しないと、Undefined Behaviorとみなされます。
他の未定義の動作と同じように、1つのオペレーティングシステム、コンパイラ、コンパイラのバージョン、時刻などで動作するという理由だけで別のオペレーティングシステムで動作するわけではありません。
メルリンの答えに追加するには、これはおそらく、あなたが意図していなかった行動につながる一つのケースは以下の通りです:
#include <stdio.h>
int main(){
int *p;
{
int v = 1;
p = &v;
}
{
int w = 2;
printf("%d\n", w);
}
printf("%d\n", *p);
return 0;
}
コンパイラはv
を持っていることによって、これを最適化し、w
に同じ割り当てを共有することスタックこの場合も、コンパイラはこれを最適化しないかもしれません。そのため、囲みブロックの終了後に変数へのポインタを使用する動作が定義されていません。プログラムは、 "2"、 "1"、 "2"、 "2"、または "2"を出力することがあります。
最後の段落が間違っています。 C99§6.8.5.3「If節-1が 宣言である場合、それが宣言する識別子のスコープは、宣言の残りの部分と、ループ全体であり、他の2つの表現を含みます。メインの残りの部分。 –
@Matthew:あなたはレキシカルスコープだけでなく、生涯を参照してもよろしいですか? – cdhowie
私はそれが両方だと信じています。 "節-1はループの初期化を指定し、おそらくループ**で使用するために1つまたは複数の変数**を宣言します"(強調が追加されています)。 C++標準(§6.5.3)では、シミュレートされたブロックの作成方法をより明確に説明しています(ただし、これと同じですが)。 –
屋が、それは時々動作しますが、1つは、それが時々 バスエラーが発生していないだけでなく、でも、プログラム全体のクラッシュを引き起こす可能性があります...それが動作することを確認することはできません...
私はUに例を与える
これを見てみましょう。.. http://www.functionx.com/cpp/examples/returnreference.htm
をここで彼は...スコープ外になる変数の参照を返すために(ビッグ失態を)しようとしている、それが動作..but ....
保証はできません。そのより良い(ベストは良くない)範囲外のデータへの参照を返さないようにする
この特定のケースでは、コンパイラの最適化設定によって動作が異なることがあります。ここでも、Cの標準は何が起こるかを定義していないので、ここでは何も設定されていません。 –