File1.cにあります
int arr[10];
そしてFile2.cで
extern int *arr;
int main()
{
arr[0]=10;
return 0;
}
これで発生する可能性のある問題とその理由は何ですか?
配列はポインターではありません。メモリアクセスがおかしくなります。
にはFile1.c
、次のメモリ レイアウトがあります。
+---+---+---+---+---+---+---+---+---+---+
+ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+---+---+---+---+---+---+---+---+---+---+
^
arr
ではFile2.c
、メモリ レイアウトがあることをコンパイラに伝えています。
+-------+
| ptr |
+-------+
^
arr
ここで、ポインタはおそらく整数を格納できる場所を指しています。
extern int *arr;
コンパイラは、からアクセスするためにまったく異なることをしなければなりませんextern int arr[];
。
書かれているように、最も可能性の高い結果は、コンパイラが null ポインターを逆参照するためのクラッシュです。ただし、動作は未定義であり、何でも可能です。あなたはコンパイラに嘘をつきました。コンパイラは自分自身を取り戻します—嘘をつくのは好きではありません。
配列はポインターではありません。
arr
は配列として定義されているので、これも配列として宣言します。
extern int arr[10]; // file2.c
そうしないと、プログラムは未定義の動作を呼び出します。