为什么这会产生分段错误?
#include<stdio.h>
void foo(int **arr) {
arr[1][1]++;
}
main() {
int arr[20][20];
printf("%d\n",arr[1][1]);
foo((int**)arr);
printf("%d\n",arr[1][1]);
}
#include<stdio.h>
void foo(int **arr) {
arr[1][1]++;
}
main() {
int arr[20][20];
printf("%d\n",arr[1][1]);
foo((int**)arr);
printf("%d\n",arr[1][1]);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
详细信息请参见此处
现在考虑以下内容,
输出:
Details here
Now consider the following,
Output :
int[2][2]
在内存中的样子如下:int[2] int[2]
也就是说,一个数组后面紧跟着另一个数组。
int[2]
在内存中的样子如下:int int
也就是说,一个 int 后面紧跟着另一个 int。
因此,这也是
int[2][2]
在内存中的样子:如果将
arr
转换为int**
,我我将调用结果p
。然后它指向同一个内存。当您执行p[1][1]
时,您不会得到arr[1][1]
。相反,程序执行的操作是读取p[1]
处的值,将其调整为 int 的大小,然后取消引用。如果第二个 int 包含值“21”,那么您刚刚尝试取消引用指针“25”(如果int
是 4 个字节)。那是不对的。数组与指针不同,二维数组当然也与指向指针的指针不同。
Here's what an
int[2][2]
looks like in memory:int[2] int[2]
That is, an array immediately followed by another array.
Here's what an
int[2]
looks like in memory:int int
That is, an int immediately followed by another int.
So, here's also what an
int[2][2]
looks like in memory:If you cast
arr
to anint**
, I'm going to call the resultp
. Then it points to the same memory. When you dop[1][1]
you don't getarr[1][1]
. What the program does instead is, it reads the value atp[1]
, adjusts that up by the size of an int, and dereferences it. If that second int contained, say, the value "21" then you have just tried to dereference the pointer "25" (ifint
is 4 bytes). That ain't right.Arrays are not the same as pointers, and 2-D arrays are certainly not the same thing as pointers-to-pointers.
因为 foo 期望一个指向 int 的指针,而您正在向它传递一个指向 20 int 数组的指针。转换它不会改变它不是正确类型的事实。
Because foo expect a pointer to a pointer to int and you are passing it a pointer to an array of 20 int. Casting it won't change the fact that it isn't the correct type.
如果你像这样改变它,你会得到预期的结果:
If you change it like this, you get the expected result:
foo
需要知道数组大小(嗯,至少是第二个数组维度,第一个不需要),否则它无法为[1][ 执行必要的指针算术1]
。foo
needs to know the array size (well, at least the second array dimension, first isn't needed), otherwise it can't do the necessary pointer arithmetic for the[1][1]
.问题是 2d 数组的 int arr[20][20] 意味着该数组存储为 1d 数组,并且行是一个接一个地存储的。当您对 int **arr 进行索引时,您实际上从数组的第一行获取第二个元素,然后取消引用它并在那里获取第一个元素。
Problem is that
int arr[20][20]
for 2d array means that this array is stored as 1d array, and lines are stored one after other. when you do indexing toint **arr
you actually take 2nd element from first line of array, then you dereference it and take first element there.