指针数组 - 外部问题

时间:2011-06-17 12:39:48

标签: c arrays pointers segmentation-fault extern

档案1.c

int a[10];

文件main.c:

extern int *a;

int main()
{
    printf("%d\n", a[0]);
    return 0;
}

给我一​​个段错误!出了什么问题?

5 个答案:

答案 0 :(得分:24)

当作为参数传递给函数时,或者在赋值运算符的右侧转换为r值时,数组会分解或隐式转换为指针。如下所示:

int array[10];
int* a = array;  //implicit conversion to pointer to type int

void function(int* a);
function(array);  //implicit conversion to pointer to type int

工作得很好。但并不意味着数组本身就是指针。因此,如果您像处理指针一样处理数组,那么您实际上将数组类型视为 - 如果它是一个将地址保存到int对象的指针。由于您的数组实际上是一个int个对象的序列,而不是指向int个对象的指针,因此您实际上试图取消引用一些未指向任何有效的内存位置(即第一个array中的槽是一个数字整数值,如0,就像取消引用NULL一样。所以这就是为什么你是segfaulting。请注意,如果你做过这样的事情:

int array[] = { 1, 2, 3, 4, 5};
int b = *array;

这仍然有效,因为array再次被隐式转换为指向保存整数值序列的内存块的指针,然后取消引用以获取第一个序列中的值。但在你的情况下,通过将数组声明为当前代码模块作为外部定义的指针而不是数组,它将跳过隐式转换为通常完成的指针,并且只使用数组对象作为 - 如果它是一个指向对象本身的指针,而不是一个对象数组。

答案 1 :(得分:16)

C FAQ中解释得很清楚。还有a followup。第二个链接中的图片价值一百万美元。

char a[] = "hello";
char *p = "world";

enter image description here

简答:使用extern int a[]

答案 2 :(得分:2)

有点晚了,刚刚输入(并关闭)此问题的副本。这里的答案没有提到头文件...

如果将数组a的声明放在它所属的头文件中,而不是将其放在.c文件中,则会在编译时捕获该问题。然后,头文件应该包含在两个.c文件中,编译器可以看到你声明的内容是错误的。

您的头文件将包含:

extern int myarray[];

如果您将error: conflicting types for a声明为指针,则会收到类似“a”的内容。

答案 3 :(得分:0)

基本上你需要像这样写你的main.c:

extern int a[];

int main()
{
    printf("%d\n", a[0]);
    return 0;
}

答案 4 :(得分:0)

查看以下代码的输出。

FILE1.C

#include <stdio.h>

extern int* my_arr;

void my_print()
{
  printf("%d", my_arr);
}

的main.c

#include <stdio.h>

int my_arr[2] = {1,2};

extern void my_print();

void main()
{
    my_print();
}

输出

1

在File1.c中,my_arr是一个指针变量,其值为1.意味着my_arr []的第一个元素被赋值给它。然后,如果使用* my_arr访问内存位置ox1,则会因为不允许访问ox01而出现seg错误。

为什么my_arr指针被赋值为1(my_arr []的第一个元素)?

与汇编程序的工作方式有关。阅读this article

为什么您的代码无法访问0x01?

我知道它与操作系统有关,不允许用户代码访问某些地址空间。这是我所知道的一切。如果您想了解更多信息,请谷歌。