指针数组外部问题

发布于 2024-11-16 01:56:46 字数 225 浏览 4 评论 0原文

文件 1.c

int a[10];

文件 main.c:

extern int *a;

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

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

File 1.c

int a[10];

File main.c:

extern int *a;

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

Gives me a segfault! What's going wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱给你人给你 2024-11-23 01:56:46

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

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)。这就是你出现段错误的原因。请注意,如果您做了这样的事情:

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

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

Arrays decompose, or are implicitly converted to pointers when passed to a function as an argument, or when converted to an r-value on the right-hand-side of the assignment operator. So something like:

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

works just fine. But that does not mean that arrays themselves are pointers. So if you treat an array like a pointer as you've done, you're actually treating the array type as-if it was a pointer that held the address to an int object. Since your array is actually a sequence of int objects, and not pointers to int objects, you're actually trying to dereference to some memory location that isn't pointing to anywhere valid (i.e., the first slot in array is a numerical integer value like 0 which would be like dereferencing a NULL). So that is why you're segfaulting. Note that if you had done something like this:

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

That still works, since array is again implicitly converted to a pointer to the memory block that is holding a sequence of integer values and is then dereferenced to get the value in the first sequence. But in your case, by declaring your array to the current code module as an externally defined pointer, and not an array, it will skip over the implicit conversion to a pointer that is normally done, and just use the array object as-if it were a pointer to an object itself, not an array of objects.

装纯掩盖桑 2024-11-23 01:56:46

C 常见问题解答中有很好的解释。还有后续。第二个链接中的图片价值一百万美元。

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

在此处输入图像描述

简短回答:使用 extern int a[]

Well explained in the C FAQ. And there is a followup. The picture in the second link is worth a million bucks.

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

enter image description here

Short answer: use extern int a[].

财迷小姐 2024-11-23 01:56:46

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

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

您的头文件将包含:

extern int myarray[];

如果您将 a 声明为指针,您将得到类似“错误:a 的冲突类型”的信息。

A bit late, a duplicate of this problem was just entered (and closed). The answers here don't mention header files...

The problem would be caught at compile time if you put the declaration of array a in a header file, where it belongs, instead of putting it in the .c file. The header file should then be included into both .c files and the compiler can see that what you have declared is wrong.

Your header file would contain:

extern int myarray[];

You will get something like "error: conflicting types for a" if you declare a as a pointer instead.

对你再特殊 2024-11-23 01:56:46

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

extern int a[];

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

Basically you'd need to write your main.c like this:

extern int a[];

int main()
{
    printf("%d\n", a[0]);
    return 0;
}
撕心裂肺的伤痛 2024-11-23 01:56:46

查看以下代码的输出。

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();
}

内的 File1.c my_arr输出

1

是一个值为 1 的指针变量。这意味着 my_arr[] 的第一个元素已分配给它。然后,如果您使用 *my_arr 访问内存位置 ox1,则会出现段错误,因为不允许您访问 ox01。

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

与汇编程序的工作方式有关。阅读这篇文章

你的代码无法访问0x01?

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

Check out the output of the following code.

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();
}

output

1

inside File1.c my_arr is a pointer variable that has the value of 1. meaning the 1st element of my_arr[] was assigned to it. Then if you use *my_arr to access memory location ox1, you get seg fault because you are not allowed to access ox01.

Why my_arr pointer was assigned 1 (the first element of my_arr[])?

Has to do with how assembler works. Read this article

Why your code can't access 0x01 ?

I know it has to do with the operating system not allowing some address space to be accessed by user code. Thats all I know. google it if you want more info.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文