OK, I’m having trouble understanding pointers to pointers vs pointers to arrays.
Consider the following code:
char s[] = "Hello, World";
char (*p1)[] = &s;
char **p2 = &s;
printf("%c\n", **p1); /* Works */
printf("%c\n", **p2); /* Segmentation fault */
Why does the first printf work, while the second one doesn’t?
From what I understand, ‘s’ is a pointer to the first element of the array (that is, ‘H’).
So declaring p2 as char** means that it is a pointer to a pointer to a char. Making it point to ‘s’ should be legal, since ‘s’ is a pointer to a char. And thus dereferencing it (i.e. **p2) should give ‘H’. But it doesn’t!
Your misunderstand lies in what
sis. It is not a pointer: it is an array.Now in most contexts,
sevaluates to a pointer to the first element of the array: equivalent to&s[0], a pointer to that'H'. The important thing here though is that that pointer value you get when evaluatingsis a temporary, ephemeral value – just like&s[0].Because that pointer isn’t a permanent object (it’s not actually what’s stored in
s), you can’t make a pointer-to-pointer point at it. To use a pointer-to-pointer, you must have a real pointer object to point to – for example, the following is OK:If you evaluate
*p2, you’re telling the compiler to load the thing thatp2points to and treat it as a pointer-to-char. That’s fine whenp2does actually point at a pointer-to-char; but when you dochar **p2 = &s;, the thing thatp2points to isn’t a pointer at all – it’s an array (in this case, it’s a block of 13chars).