int *p = a
文字どおりに解釈される は、 に格納されている値を取得し、に格納するメモリ アドレスa
として解釈しようとします。計算上は合法ですが、C++ では明示的な型キャストなしではこれを許可しません。通常、これはやりたいことではないからです。p
int *p = a
ステートメントが異なる理由*p = a
は単純です: 最初のステートメント、次の省略形
int *p;
p = a;
はポインタを初期化しているため、RHS のメモリ アドレスが期待されますが、2 番目のステートメントは が指す場所に値を代入しているp
ため、(この場合) RHS の整数が期待されます。
p
を指すように初期化したい場合は、代わりにora
を使用できます。 whereはアドレス演算子です。初期化されていないポインターを逆参照しようとしないでください。基本的に任意の場所でメモリにアクセスすることになり、セグメンテーション違反 (クラッシュの結果) を引き起こしたり、プログラム内の他のデータの上書きを開始したりします (あいまいで再現不可能なバグが発生します)。int * p = &a
p = &a
&
サンプルコードを実行するp
と、 が のアドレスを指すように割り当てられていない&a
ため、正確に異なる値が得られます。ゼロ以外の値を取得する理由についての簡単な背景: ローカル変数は、関数呼び出しと戻りアドレスに関する情報も格納するstackと呼ばれるメモリの特別な領域から割り当てられます。各プロセスには独自のスタックがあります。ただし、重要なのは、スタックの未使用の領域が実際にはゼロにされたり、使用前にクリーンアップされたりしないことです (デバッグ ビルドを除き、またはp
a
p
0xCCCCCCCC
0xBAADF00D
初期化されていないポインターへ)。コンパイラが自動的にデフォルト値を設定しない場合 (そしてリリース ビルドでは一般に、効率のためにそのような自動初期化は行われません)、表示されているのは、プログラムが設定される前に割り当てられたメモリにたまたまp
配置されていたものです。そのスタック フレームをアップします。p