avd*_*avd 7 c arrays segmentation-fault
#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]);
}
Run Code Online (Sandbox Code Playgroud)
N 1*_*1.1 10
假设你声明:int arr [10] [20];
什么类型的arr?
你可能认为这是int **,但这是不正确的.
int (*)[20]当它衰变时它实际上是类型(比如当你将它传递给函数时);
数组衰减仅适用一次.
现在考虑以下,
#include<stdio.h>
#include<stdlib.h>
void foo(int arr[][20]) {
arr[1][1]++;
}
main() {
int (*arr)[20];
arr = malloc(sizeof(int (*)[]) * 2); //2 rows & malloc will do implicit cast.
printf("%d\n",arr[1][1]);
foo(arr);
printf("%d\n",arr[1][1]);
}
Run Code Online (Sandbox Code Playgroud)
输出:
$ gcc fdsf.c && ./a.out
0
1
arr和arr + 1指向20个整数的数组.
arr + 0 - > int int int ... int(20 ints,contiguous)
[0] [0] [0] [1]
arr + 1 - > int int int ... int(20 ints,contiguous)
[1] [0] [1] [1]
这是int[2][2]内存中的样子:
int[2] int[2]
也就是说,一个数组紧跟另一个数组.
这是int[2]内存中的样子:
int int
也就是说,一个int紧跟另一个int.
所以,这里也是int[2][2]内存中的样子:
int int int int
^ ^
| |___ this is arr[1][1]
|
|____ this is p[1], assuming sizeof(int*) == sizeof(int)
Run Code Online (Sandbox Code Playgroud)
如果你投arr了一个int**,我打算调用结果p.然后它指向相同的记忆.当你这样做时,p[1][1]你没有得到arr[1][1].该程序所做的是,它读取值p[1],通过int的大小调整,并取消引用它.如果第二个int包含,例如值"21",那么您刚刚尝试取消引用指针"25"(如果int是4个字节).那是不对的.
数组与指针不同,2-D数组肯定与指针指针不同.
如果你这样改变它,你会得到预期的结果:
#include<stdio.h>
void foo(int arr[][20]) {
arr[1][1]++;
}
int
main() {
int arr[20][20];
arr[1][1] = 1;
printf("%d\n",arr[1][1]);
foo(arr);
printf("%d\n",arr[1][1]);
}
Run Code Online (Sandbox Code Playgroud)