2010-10-01 65 views
0

快速C问题在这里。我们最近一直在玩双,三,甚至四分球。我们虽然我们对事物的把握,直到我们遇到了这个问题...C - 通过函数调用迷路的双指针

char ***data; 
data_generator(&data); 
char **temp = data[0];   
printf("printing temp[%d]: %s\n",0, temp[0]); 
printf("printing temp[%d]: %s\n",1, temp[1]); 
dosomething(temp); 

int dosomething(char **array) { 

    printf("printing array[%d]: %s\n",0, array[0]); 
    printf("printing array[%d]: %s\n",1, array[1]); 
    ...... 
} 

int data_generator(char ****char_data) { 
    char *command1[2]; 
    char *command2[2]; 

    command1[0] = "right"; 
    command1[1] = "left"; 

    command2[0] = "up"; 
    command2[1] = "down"; 

    char **commandArray[2]; 

    commandArray[0] = command1; 
    commandArray[1] = command2; 

    number_of_commands = 2; 

    if(number_of_commands > 1){ 
    *char_data = commandArray; 
    } 

    return number_of_commands - 1; 
} 

而这种打印出...

printing temp[0]: right 
printing temp[1]: left 
Segmentation fault 

貌似我对所发生的指针一些误解同时通过一个函数。有什么想法吗?

+0

呃,char ***数据的大小是4字节(在一个32位机器上),你的代码假设它有点大...... – 2010-10-01 04:28:24

+0

我没有看到任何分配... – 2010-10-01 04:32:32

回答

3
*char_data = commandArray; 

你是把叠层(自动)数组的地址在外部存储器位置。这是灾难的原因(未定义的行为),因为commandArray的生命期一旦结束,data_generator就会返回。 commandArray的元素也是如此,它们本身是指向堆栈数组元素的指针。

+0

感谢答复。为了确保我在这里清楚,因为commandArray中的所有元素都在data_generator的范围内声明,所以只要data_generator返回,系统就可以取消分配这些对象。那是对的吗?我用于Objective-C,其中“保留”是解决方案。什么是C等价物? – Staros 2010-10-01 04:58:15

+0

它可以(也可以,虽然你可能不会马上被咬),但是会释放所有的自动变量。这包括数组'command1','command2'和'commandArray'。一般的解决方案是使用调用者提供的内存,或者'malloc'。 – 2010-10-01 05:09:47

0

变化:

char *command1[2]; 
char *command2[2]; 

到:

static char *command1[2]; 
static char *command2[2]; 

这将保持命令1 []和在保留存储器命令2 []。

或者malloc()他们,就像其他海报推荐的那样,尽管正确使用malloc'c内存需要比我在这里讨论的更多的考虑。

+0

你应该提到,对于很多实际的例子(当涉及多于常量时),这将使它不可重入。 – 2010-10-01 18:07:32