我理解为什么int (*arr2d)[3]
是好的,为什么**arr2d
作为期望传递2d数组的函数的函数参数是坏的。我知道2d数组衰减到指向数组的指针而不是指向指针的指针。我也知道为什么3
(列数)是处理二维数组的函数的必要信息(索引到大于1的维数组的基础指针数学需要数组的大小第一个之后的所有维度。
然而,我不知道seg故障发生的原因。如果一个2d数组可以被解引用两次来检索它的第一个元素,为什么当它被视为指向指针时不是这样?我知道2d数组不等同于指针指针。我想知道为什么我不能解除后者的两次在这种情况下。请考虑以下两个示例。
在第一个中,一个2d数组被传递给一个期望指向指针的函数,当它在所述函数中被解除引用两次时会导致seg错误。
void printFirst(int **arr2d) {
printf("%d\n",**arr2d);
}
void printFirst_corrected(int (*arr2d)[3]) {
printf("%d\n",**arr2d);
}
int main(void) {
int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
printf("%p\n",arr); // prints some address a0
printf("%p\n",*arr); // prints the same address a0
printf("%d\n",**arr); // prints 1
printFirst_corrected(arr); // works, prints 1
printFirst(arr); // why does this fail? (seg fault, core dumped)
}
在第二个中,一个2d数组被转换为指向指针然后两次解引用,导致seg错误。
int main(void) {
int arr[][3] = {{1,2,3},{4,5,6},{7,8,9}};
int **nums2 = (int**)arr;
printf("%p\n",arr); // prints some address a0
printf("%p\n",*arr); // prints the same address a0
printf("%d\n\n",**arr); // prints 1
printf("%p\n",nums2); // prints a0
printf("%p\n",*nums2); // prints 0x200000001
printf("%d\n",**nums2); // fails, seg fault (core dumped)
}