Reputation: 31
I've an array of pointer, When I'm trying this C code getting an error of segmentation fault. What I'm doing wrong here?
char *ptr[] = {"exam","example","testexample"};
printf("%c\n",*(*(ptr+2)+7));
printf("%s\n",*(*(ptr+2)+7));
In output of First print statement giving the expected result
printf("%c\n",*(*(ptr+2)+7));
m
but the second one instead of giving output of
mple
is giving
printf("%s\n",*(*(ptr+2)+7)); Segmentation fault (core dumped)
What I'm doing wrong here?
Upvotes: 0
Views: 160
Reputation: 133929
The problem is the use of the expression *(*(ptr+2)+7)
- it is hard to see what it does. That construct is used mostly by beginners who do not know C intimately yet. That is why C has a syntactic sugar for it: *(*(ptr+2)+7)
is exactly equivalent to ptr[2][7]
, which is the form you should be using.
Now, ptr[2][7]
clearly is a char
, but %s
expects a pointer to a char
, the first character in a null-terminated string, so let's pass in a pointer to that character:
printf("%s\n", &ptr[2][7]);
Upvotes: 0
Reputation: 81
((ptr+2)+7) is a char value
So the first statement is correct since "%c" tells printf that first parameter is a char:
printf("%c\n",*(*(ptr+2)+7));
But in the second statement , "%s" tells printf that first parameter is (char *), that is a pointer to a char. That way, when program executes
printf("%s\n",*(*(ptr+2)+7));
looks at the value of ((ptr+2)+7) ( a char value, in this case 'm' ) as if it where a char pointer. That is the reason of the segmentation fault.
So the corrected secon statement would be
printf("%s\n",*(ptr+2)+7);
Hope this helps.
Upvotes: 0
Reputation: 310980
The type of the expression
*(*(ptr+2)+7)
is char
. So the first call of printf
is correct.
But the second call is incorrect because the format specifier %s
expects an argument of the type char *
. So the value of the character obtained by the expression *(*(ptr+2)+7)
that is the character 'm'
(that for example in ASCII has the value 100
) is interpreted as an address.
In the second call just use
*(ptr+2)+7
Here is a demonstrative program
#include <stdio.h>
int main(void)
{
char *ptr[] = { "exam", "example", "testexample" };
printf( "%c\n", *( *( ptr + 2 ) + 7 ) );
printf( "%s\n", *( ptr + 2 ) + 7 );
return 0;
}
Its output is
m
mple
Upvotes: 2
Reputation: 23332
Your argument *(*(ptr+2)+7)
evaluates to one character with the value 'm'
, which (on an ASCII-based platform) is the same as the number 109.
When you do
printf("%s\n",*(*(ptr+2)+7));
this is exactly the same as
printf("%s\n",'m');
It gets compiled to machine code that loads the number 109into a register and pushes that register on the stack. It doesn't tell
printfanything about _where it found_ that
'm'` -- only that one raw ASCII value gets passed to the function.
printf
then tries to interpret the 109 not as a character itself but as a pointer to some characters -- because that's what you asked it to do by writing %s
. This, unsurprisingly, goes horribly wrong, since 109 is not the address of anything the program is allowed to access.
If you want to print the tail end of the string, you could instead write
printf("%s\n", *(ptr+2)+7 );
where you don't apply the *
operator to the pointer you want to pass.
Upvotes: 0