2012-11-02 30 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結尾)字符串打印,最有可能訪問隨機存儲器。