#include<stdio.h>
int main(void)
{
char * p= "strings are good";
printf("%s",*p);
return 0;
}
Could somebody please tell me why I am getting segmentation fault here?
#include<stdio.h>
int main(void)
{
char * p= "strings are good";
printf("%s",*p);
return 0;
}
Could somebody please tell me why I am getting segmentation fault here?
Could somebody please tell me why I am getting segmentation fault here?
If a conversion specification is invalid, the behavior is undefined.282) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
1 undefined behavior behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements.
2 NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
*p
is of type char
. %s
expects argument of type char *
. This will invoke undefined behavior. In this case anything could happen. Sometimes you may get the expected result and sometimes not. This may also cause program crash or segmentation fault (which is the case here).
For %s
, you need to pass the starting address of the sting/literal.
Change
printf("%s",*p);
to
printf("%s",p);
Here's the problem:
printf("%s",*p);
printf
will parse the const char *
format string, in your case: "%s"
, and will deduce that the first argument other than the format will be a char *
, too.
Now, because you dereference the pointer, you're passing a single char (char
, without the *
)
Now if you compare the size of a char to the size of a char pointer:
printf("%d vs %d\n", sizeof(p), sizeof(*p));
You'll see that a char pointer is 4 (or 8 for 64 bits) times the size of a char.
Consider what you're actually doing as forcing printf
to cast the value of a char to a pointer, and then use that pointer to read a string:
const char *p = "foobar";
printf("%p\nWhereas you wanted: %p\n", (void *) *p, (void *) p);
Output:
0x66 //not a valid pointer, too small
Whereas you wanted: 0x80485c8 //<-- actual address may vary
The solution:
printf("%s\n", p);
Don't dereference the pointer, just pass it as is.
Just a little tip: learn to love the storage class modifier const
. It's a useful reminder in this case:
char *p;
//some code
p = "a string";
//more code, or passing p to a function that attempts to do:
p[0] = 'A';//ERROR!!
Whereas:
const char *p;//I can SEE p points to a constant
p = "a string";
p[0] = 'A';//error, the declaration of p tells me why
The const
is a visual reminder that whatever you're going to do with p
, you should keep in mind that it points to a constant, and the value can't be edited.
You are passing a single char as a string type(%s) in printf formatted output. Change it to p