2012-06-06 212 views
8

當我嘗試下面的代碼中的第二個選項來初始化names時,出現了分段錯誤。我猜想第二個選項在概念上是不正確的。有任何想法嗎?爲什麼不能使用指向char指針的指針而不是char指針數組?

char *names[] = { 
      "Alan", "Frank", 
      "Mary", "John", "Lisa" 
     }; 

char **names = { 
      "Alan", "Frank", 
      "Mary", "John", "Lisa" 
     }; 
+0

'char name [] =「Allan」;' 'char ** names = &name;' –

+0

'也許告訴我們爲什麼你這麼成**。除了通過參數從函數返回外,它們幾乎沒有用處。 –

+0

@Agent_L我沿着這本書「Learn C The Hard Way」(http://c.learncodethehardway.org/book/learn-c-the-hard-waych16.html),在那裏有一個練習「重寫所有在這個程序中的數組用法,以便它是指針。「 –

回答

6

是的。在第一種情況下,你有一個指針數組。每個指針指向一個單獨的項目(阿蘭,弗蘭克...)

第二個聲明

char **names; 

意味着名字是一個指針的指針[你不能初始化一組這樣的字符串。如在

char *str = "hello" 
char **names = &str; 
2

它具有完全不同的存儲器佈局。你的第一個例子是指針數組。它佔據了char *大小的5倍。

然而,您的第二個示例是指向一個或多個char *預期位置的指針。無法按照您的方式初始化它。

+0

謝謝,第二個選項初始化的正確方法是什麼 –

+2

第一種方法是正確的方法。 char **名稱不是數組。它是一個指向指針的指針,因此可以保存上面公佈的指針的地址。 –

+0

@stressed_geek你可以有一個char **(第二種方法)指向一個數組(第一種方式)。但首先,你必須初始化它。 'char * names [] = {...}; char ** n2 = &names;'可能是一種方法... – glglgl

2

在第一種情況下,您有一組char*。這意味着,你已經爲5個char *變量(數組的條目)分配了內存,整齊地一個接一個地坐在內存中。另外,它們中的每一個都被初始化爲每個字符串的開頭。

在第二種情況下,您有一個char **類型的指針。你只有一個指針足夠的內存。

(我已經跳過討論分配給每個字符串的內存,這可能是在兩種情況下相同的,但它是無關緊要這裏)

0

它不會導致用gcc一個賽格故障。但是試圖同這一個整數數組可能可能解釋了爲什麼它沒有很大的意義:

char* names[] = { "Dennis", "Richie" }; 
char** more_names = { "Sarah", "O'connor" }; 

printf("Name: %s %s\n", names[0], names[1]); 
printf("Name: %s %s\n", more_names + 0, more_names + 1); 

int numbers[] = { 0, 1 }; 
int x = 2, y = 3; 
int* more_numbers = { &x, &y }; 

printf("Numbers: %d, %d\n", numbers[0], numbers[1]); 
printf("Numbers: %d, %d\n", *(more_numbers + 0), *(more_numbers + 1)); 

奇怪的是,這個例子實際上產生了整型數組的預期結果。但是gcc確實會產生警告。