2012-11-02 33 views
-3

我确信之前已经问过这个问题,但粗略的谷歌和堆栈溢出搜索没有找到答案。解引用数组vs指针

#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)的语法糖。这是正确的,无论是指针和数组?然而,ab似乎获得了不同的行为。

谢谢!

+3

您确定您已启用所有警告吗?并阅读所有200万SO帖子,告诉你,一个数组是不一样的指针? –

+0

@KerrekSB很明显 - 这就是代码演示的内容。我只是要求解释。 –

回答

3

char **b说“在b分的地方,b[0],有一个指向char的指针。而且,如果我用b[1]b[2],......,这些都还指向char。”

相比之下char a[128][1024]说:‘a是1024字节的128个阵列。’当你做到这一点,在那里a是地方,有没有指针。只有字符。在内存中,它看起来像连续131,072 char(128•1024 = 131,072)。

当您指定char **b = a时,假设编译器允许,您将b设置为a的地址。当你使用b[0]时,应该有一个指针。但没有。那里只有char。当您将b[0]传递给printf时,编译器会转至b指向的位置,加载几个字节,就好像它们是指针一样,并将结果值传递给printf。然后printf崩溃,因为这些字节指向一些不好的位置。

b的正确定义是char (*b)[1024] = a;

+0

啊。这很有道理。谢谢你的解释。 :) –

0

char **b = a; 

是一种类型的错配achar[][]未经索引用于为char *

您可能希望切换全部编译器警告(在gcc这是通过-Wall doen)。

此行

printf("%s\n", b[0]); 

解除引用一个指针的指针到字符,这是一个地址值。然后它尝试将地址值的值作为(0结尾)字符串打印,最有可能访问随机存储器。