Reputation: 115
I a am trying to understand the results I am receiving when referencing the pointer 'p'. I have placed comments in-line, stating what I believe is happening.
#include <stdio.h>
main()
{
char *words[] = { "hello", "world" };
char **p = words; // p is now pointing to words[0]?
++p; // p now points to "world"
printf("%s\n", *p); // Prints the character string 'world', pointed to by p
printf("%c\n", *p[0]); // Returns 'w'
printf("%c\n", *p[1]); // Should return 'o'? Returns garbage
printf("%c\n", *++p[0]); // Returns 'o'?
}
My understanding is that after:
char **p = words;
That p now points to the first character pointed to by words[0], i.e., the 'h' in 'hello'. Then after:
++p
p now points to the first character pointed to by the pointer at words[1], i.e., the 'w' in 'world'.
The results:
world
w
<blank space>
o
If *p[0] returns the character 'w'. Then, why does *p[1] return garabage? I am trying to understand how the contents pointed to by the pointers in *words is organized in memory, then, where p is pointing to after each call.
Update
By changing the following lines:
printf("%d\n", *p[0]);
printf("%d\n", *p[1]);
printf("%d\n", *++p[0]);
The results are now:
119 // 'w'
1 // 'SOH' -- Start of heading
111 // 'o'
Now, what exactly is the SOH character, in this context?
Upvotes: 0
Views: 81
Reputation: 206697
There is some misunderstanding.
The memory layout after:
char *words[] = { "hello", "world" };
will look something like:
words[0] words[1]
| |
v v
+-----------+-----------+
| ptr1 | ptr2 |
+-----------+-----------+
ptr1
+---+---+---+---+---+------+
| h | e | l | l | o | '\0' |
+---+---+---+---+---+------+
ptr2
+---+---+---+---+---+------+
| w | o | r | l | d | '\0' |
+---+---+---+---+---+------+
You said:
char **p = words; // p is now pointing to world[0]?
If you meant words[0]
, then you are correct.
You also said,
That
p
now points to the first character pointed to bywords[0]
That is not correct. The type of p
is char**
. You could say *p
points to the first character pointed to by words[0]
.
Regarding the output of the program...
You have a line:
++p;
This line changes p
so that it points to words[1]
.
The line
printf("%c\n", *p); // Should return 'w'? But returns garbage
is cause for undefined behavior since the type of *p
is not an int
that represents a char
. Type of *p
is char*
, not char
.
The line
printf("%c\n", *p[0]); // Returns 'w'
prints w
since p[0]
is equal to ptr2
. As you can see from the memory layout, *ptr2
evaluates to 'w'
. Hence, you get w
in the output.
The line
printf("%c\n", *p[1]); // Should return 'o'? Returns garbage
is also cause for undefined behavior.
Due to operator precedence, *p[1]
is equivalent to *(p[1])
, which is equivalent to *(*(p+1))
. Since p
already points to words[1]
, (p+1)
points to invalid memory.
Upvotes: 1
Reputation: 7632
You should use warning to show you basic error
a.c:10:5: warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat]
*p
is a pointer to a char.
Try:
printf("%s\n", *p);
printf("%c\n", *p[1]);
Here p[1]
can be the third element of words
as there is no third element you read garbage value.
For ++p[0]
p[0]
points to "world"
with ++
this point to "orld"
then with *
you print the first char
so o
.
To undrestand pointer you can use print
with %p
to see your pointed adress.
Upvotes: 0