私は今 C を学んでいます。最近はポインターを勉強しています。質問があります。
int *ptr; //declare the ptr
ptr = &var; //init the ptr with the address of the variable var
これらの行で、ポインターを作成し、ptr を変数にリンクしました。私の質問はこれです。ポインターを宣言int *ptr;
し、アドレスで初期化しない場合、このポインターはどこを指していますか?
C では、特に指定しない限り、通常、変数は初期化されません。
int a; // not initialized
int b = 1; // initialized
int arr[10]; // not initialized
int brr[4] = { 1 }; // initialized as { 1, 0, 0, 0 }
void * p; // not initialized
void * q = &a; // initialized
(常にゼロで初期化される、静的ストレージまたはスレッド ローカル ストレージを持つ変数には例外があります。)
初期化されていない変数の値を取得しようとすることは許可されていません。初期化されていない変数でできる唯一のことは、現在の値にアクセスせず、新しい値を割り当てることだけです。初期化または割り当ての前は、変数の現在の値は「不確定」であり、アクセスしようとしてはいけません。これを行うと、未定義の動作が発生します。
これはすべての変数に当てはまりますが、特にポインター変数に当てはまります。値を割り当てるまで、意味のある値はありません。
void * p; // not initialized
if (p) { /*...*/ } // undefined behaviour!
printf("%p\n", p); // undefined behaviour!
p = &a; // now p has a well-defined value
未定義の動作を引き起こしているアクションの専門用語は、いわゆる「左辺値変換」です。それは、名前付き変数 (「左辺値」) を取り、その内容を使用する瞬間です。たとえば、C11、6.3.2.1/2 は次のように述べています。
左辺値が自動保存期間 [...] のオブジェクトを指定し、そのオブジェクトが初期化されていない (初期化子で宣言されておらず、使用前に割り当てが実行されていない) 場合、動作は未定義です。
この場合、それはどこでも指します。あなたは知りません。ポインターの内容は、以前のメモリ位置にあったものになります。したがって、これは非常に危険であり、避ける必要があります。ポインターは常に NULL で初期化する必要があります。そうすれば、定義された方法で「何も」を指すことになります。
C の他の非静的変数と同様に、自動的に初期化されません。これには、メモリ スロットにあったジャンク データが含まれているため、適切な値を割り当てる前に参照することはお勧めできません。
ランダムなメモリ位置を指します。通常、このようなポインターを逆参照すると、segfault が発生します。