2012-06-06 213 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确实会产生警告。