Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a pointer to a pointer incompatible with a pointer to an array?

Tags:

arrays

c

pointers

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!

like image 460
Meta Avatar asked Oct 27 '11 23:10

Meta


1 Answers

Your misunderstand lies in what s is. It is not a pointer: it is an array.

Now in most contexts, s evaluates 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 evaluating s is 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:

char *p = s;
char **p2 = &p;

If you evaluate *p2, you're telling the compiler to load the thing that p2 points to and treat it as a pointer-to-char. That's fine when p2 does actually point at a pointer-to-char; but when you do char **p2 = &s;, the thing that p2 points to isn't a pointer at all - it's an array (in this case, it's a block of 13 chars).

like image 190
caf Avatar answered Oct 27 '22 18:10

caf