从指针进行数组索引
array indexing from a pointer
请考虑以下代码:
static char a[2][2] = {
{ 1, 2 },
{ 3, 4 },
};
int main()
{
char **p = (char**)a; // needs cast, or compiler complains (which makes sense)
printf("%pn", p);
printf("%pn", &a[1][0]);
printf("%dn", a[1][0]);
printf("%pn", &p[1][0]); // why null? why doesn't compiler complain about this?
printf("%dn", p[1][0]); // segfault, of course
return 0;
}
产生以下输出:
0x804a018
0x804a01a
3
(nil)
Segmentation fault
我知道数组可以衰减到指针。 我不明白的是为什么编译器(g++(会让我尝试做相反的事情。 如果 p 是一个字符**,为什么它让我在没有警告的情况下使用 p[x][x]? 它显然甚至无法正常工作,因为生成的指针为空。
顺便说一句,我问的是来自第三方的代码,这显然对他们有用。 (在Windows中编译,而不是使用g ++(。 因此,我不是在寻求有关如何修复此代码的建议,我已经知道如何做到这一点。 我只是想了解为什么编译器不抱怨,以及为什么结果是空指针。
谢谢。
您根本无法像char**
一样开始处理 2D char
数组。在内存中,数组如下所示:
| 1 | 2 | 3 | 4 |
每个元素都跟在前一个元素之后。数组名称将被隐式转换为指向其第一个元素的指针:
| 1 | 2 | 3 | 4 |
^
|
现在,如果你把这个指针转换成一个char**
,你说"如果你取消引用这个指针,你会发现一个char*
",这是一个彻头彻尾的谎言。如果取消引用指针,您将获得值为 1
的char
,而不是指针。
然后当你做p[1][0]
时,你把p[1]
处的值(实质上是将足尖p
移动了sizeof(char*)
(作为指针,并试图取消引用它。当然,这会直接导致您出现未定义的行为。
编译器不让你做那个转换,因为这是一个愚蠢的转换。不要这样做。仅仅因为 C 型强制转换允许您这样做,这并不意味着这是一个可以操作的操作。如果没有其他演员表工作,C 型演员表将回退到reinterpret_cast
,在这种情况下,您几乎肯定会遇到未定义的行为。
实际上给出一个答案:a
是一个数组。 对于像char* p = a;
这样的语句,a
会自动衰减到指向第一个元素{ 1, 2 }
的指针,并且由于这是一个数组,它也将衰减到它的第一个元素1
。然而,对于char**p = a
,a
仍然衰减到那个array of array of char
,然后你把整个数组投射到an array of pointers to chars
:(它解释为{0x01020304, 0x????????}
(,这根本没有意义。 它是指向数组的指针,而不是指向指针的指针。 这就是为什么你需要演员阵容,因为它没有意义。
其次,当你键入 p[1]
时,它会将该数据(以及它后面的几个字节(视为char
指针数组,{0x01020304, 0x00000000}
,并返回第二个元素。 (在这种特殊情况下,我们可以看到它都是零,因为这是稍后打印在屏幕上的内容(,然后[0]
取消引用第二个恰好为 NULL 的神秘未知指针,给你一个段错误。
当你这样说时:
char a[2][2];
char **p = (char**)a;
这是一个错误。 a
不是指向字符的指针数组。它是一个存储块数组,每个存储块都是一个字符数组。
- 数组索引的值没有增加
- 并行用于C++17中数组索引范围内的循环
- 数组索引重载错误
- 通过指针与数组引用扩展数组索引序列
- SIGSEGV, 分段错误. 而 printf() 数组索引的值
- 缓冲区溢出 - 数组索引越界(严重)
- 为什么C++数组索引值是有符号的,而不是围绕size_t类型构建的(或者我错了)
- 查找下一个具有真值C++的数组索引
- 在编译时自动生成用于稀疏数组索引的switch语句
- 在数组索引上引发异常
- C++ 将二维数组索引与条件语句中的函数值进行比较
- 平衡数组索引,同时从左和右对数组求和
- 为什么C ,Devstudio,数组索引工作
- 如何对同一数组索引下的结构成员进行排序?
- 我想返回数组索引,而不是数组值
- C++相当于 Python 的:用于数组索引
- 分段错误:为什么这里的数组索引越界了
- 数组索引在地图上不是整数
- 根据用户输入的每个字母添加到数组索引
- C 数组索引