0 c++ pointers multidimensional-array
考虑以下代码:
static char a[2][2] = {
{ 1, 2 },
{ 3, 4 },
};
int main()
{
char **p = (char**)a; // needs cast, or compiler complains (which makes sense)
printf("%p\n", p);
printf("%p\n", &a[1][0]);
printf("%d\n", a[1][0]);
printf("%p\n", &p[1][0]); // why null? why doesn't compiler complain about this?
printf("%d\n", p[1][0]); // segfault, of course
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产生这个输出:
0x804a018
0x804a01a
3
(nil)
Segmentation fault
Run Code Online (Sandbox Code Playgroud)
我知道数组可以衰减到指针.我不明白为什么编译器(g ++)会让我尝试反过来.如果p是char**,为什么它让我使用p [x] [x]而不是警告?它显然甚至没有接近工作,因为结果指针为空.
顺便说一下,我问这个来自第三方的代码,显然对他们有效.(在Windows中编译,而不是使用g ++编译).所以,我不是在寻找有关如何修复此代码的建议,我已经知道如何做到这一点.我只是想了解编译器为什么不抱怨,以及为什么结果是空指针.
谢谢.
你根本无法开始治疗的二维数组char像char**.在内存中,数组看起来像这样:
| 1 | 2 | 3 | 4 |
Run Code Online (Sandbox Code Playgroud)
每个元素都遵循前一个元素.数组名称将隐式转换为指向其第一个元素的指针:
| 1 | 2 | 3 | 4 |
^
|
Run Code Online (Sandbox Code Playgroud)
现在,如果你将这个指针转换为a char**,你会说"如果你取消引用这个指针,你会发现char*"这是一个彻头彻尾的谎言.如果你取消引用指针,你将获得一个char有值1,而不是一个指针.
然后,当你这样做时p[1][0],你正在处理值p[1](基本上将pointe p一直移动sizeof(char*))作为指针并试图取消引用它.当然,这会引导您直接进入未定义的行为.
编译器没有让你做那个演员,因为这是一个愚蠢的演员.不要这样做.仅仅因为C风格的演员阵容允许你这样做,这并不意味着它是一个好的操作.reinterpret_cast如果没有其他演员工作,C风格的演员阵容将回归到,在这种情况下,你几乎肯定会遇到未定义的行为.