我确定之前已经问过这个问题,但粗略的google和堆栈溢出搜索没有找到答案。
#include <stdio.h>
int main() {
char a[128][1024];
strcpy(a[0], "hello");
strcpy(a[1], "foo");
strcpy(a[2], "bar");
char **b = a;
printf("%s\n", a[0]); //same as printf("%s\n", a)
printf("%s\n", a[2]+1); //print from 2nd char of 3rd string
printf("%s\n", b); //same as printf("%s\n", a), makes sense
printf("%s\n", b[0]); //segfault???
}
首先,为什么最后一个是段错误?我期望与数组a
具有相同的行为。如何以通用方式从b访问第n个字符串? a和b之间的治疗有何不同?
在类似的说明中,我理解它的方式,a[n]
是*(a+n)
的语法糖。这对指针和数组都是正确的吗?然而,a
和b
似乎有不同的行为。
谢谢!
答案 0 :(得分:3)
char **b
说“在b
点,b[0]
的地方,有一个指向char的指针。而且,如果我使用b[1]
,b[2]
,......,那些也是char的指针。“
相比之下char a[128][1024]
说“a
是128个char的128个数组。”当你这样做时,在a
所在的地方,没有指针。只有char。在内存中,它看起来像连续131,072个字符(128•1024 = 131,072)。
当您指定编译器允许的char **b = a
时,您将b
设置为a
的地址。使用b[0]
时,应该有一个指针。但事实并非如此。那里只有炭。当您将b[0]
传递给printf时,编译器会转到b
个点,加载几个字节,就像它们是指针一样,并将结果值传递给printf。然后printf崩溃,因为字节指向一些不好的位置。
b
的正确定义是char (*b)[1024] = a;
。
答案 1 :(得分:0)
此
char **b = a;
是一种类型不匹配,a
为char[][]
,其中没有索引使用的是char *
。
您可能希望切换所有编译器警告(gcc
这是通过-Wall
执行的。)
这一行
printf("%s\n", b[0]);
取消引用指向字符的指针,即地址值。然后它尝试将地址值值打印为(0终止)字符串,最有可能访问随机存储器。