Хорошо, мне трудно понять указатели на указатели против указателей на массивы. Рассмотрим следующий код:
char s[] = "Hello, World";
char (*p1)[] = &s;
char **p2 = &s;
printf("%c\n", **p1); /* Works */
printf("%c\n", **p2); /* Segmentation fault */
Почему первый файл printf работает, а второй - нет?
Из того, что я понимаю, 's' является указателем на первый элемент массива (то есть "H" ). Таким образом, объявление p2 как char ** означает, что оно является указателем на указатель на char. Приведение его к "s" должно быть законным, поскольку "s" является указателем на char. И, таким образом, разыменование его (т.е. ** p2) должно давать "H". Но это не так!