3

我们在 File1.c

int arr[10];

在 File2.c 中

extern int *arr;

int main()

{
   arr[0]=10;
   return 0;
}

这可能会出现什么问题,为什么?

4

3 回答 3

11

数组不是指针。内存访问将是错误的。

File1.c中,您有内存布局:

+---+---+---+---+---+---+---+---+---+---+
+ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+---+---+---+---+---+---+---+---+---+---+
^
arr

File2.c中,您已经告诉编译器您有内存布局:

+-------+
|  ptr  |
+-------+
^
arr

其中指针可能指向可以存储整数的地方。

编译器必须做完全不同的事情才能extern int *arr;extern int arr[];.

如所写,最可能的结果是由于编译器取消引用空指针而导致崩溃。但是,行为是未定义的,一切皆有可能。你对编译器撒了谎;编译器会得到自己的回报——它不喜欢被骗。

于 2012-07-11T13:47:20.657 回答
3

数组不是指针。

arr被定义为一个数组,因此也将其声明为一个数组。

extern int arr[10];   // file2.c

如果不这样做,您的程序会调用未定义的行为。

于 2012-07-11T13:45:21.673 回答
0

int arr[10];形式上,本身arr不占用内存空间;它只是一个可以在链接时确定的地址值。假设arr是100;arr[0]是内存地址 100 中的值。

extern int *arr;表单中,arr它本身就是内存中的一个变量。假设 arr 为 100,arr[0]是内存地址ptrptr的值,而是地址 100 处的内存单元的值。

编辑

gcc 生成的 asm 给出了深刻的见解:

extern int a[10];
extern int *b;

int foo(void)
{
    return a[3] + b[5];
}

_foo:
    pushl   %ebp
    movl    %esp, %ebp

    movl    _b, %eax /* 1st memory load for pointer */
    addl    $20, %eax
    movl    (%eax), %eax /* 2nd memory load for pointer  */

    addl    _a+12, %eax /* only one memory load for array */

    popl    %ebp
    ret
于 2012-07-11T13:53:03.387 回答