2
#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?

2
  • To deal with segfaults with '', randomly remove and add '' until it works -it's quicker than real debugging:) Commented Dec 17, 2013 at 12:09
  • @MartinJames: May well be, but it's not very educational, IMO... PS: to the OP: const is your friend. char *p = "some string constant" is essentially the same as auto char *p = "some string constant"; which is, in turn, the same as const char *p = "some string constant";. Write the const, to remind yourself of the fact that p[2] = 'a'; is impossible Commented Dec 17, 2013 at 12:19

3 Answers 3

8

Could somebody please tell me why I am getting segmentation fault here?

C11: 7.21.6 Formatted input/output functions:

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.

3.4.3

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);
Sign up to request clarification or add additional context in comments.

12 Comments

I have declared a pointer p to the "strings are good" , so i should deference it in order to access it right.?? Like i would do with numbers.??
@sidchelseafan Try %c if you want to dereference your pointer (to a single character). %s is probably expecting you to provide a pointer, not just the value of a character (which is what you get when dereferencing).
@sidchelseafan You probably got a seg fault because printf saw the %s and was looking to read data until it got to a null marking the end of a string. However, when you dereferenced it, you gave it just a character, so it likely read past that character and blew up.
@haccks: It's not that. It's just: the spirit of the C standard is, I think, more like this: "One shouldn't pass a char, when a pointer is expected. If the programmer does so, we don't handle this in any way: it's his/her problem, not ours". PHP was meant to be easy, so it produces notices, but will help you out. For example $undeclaredVar[] = 'Used as array'; produces a notice, but PHP will initiate the var to an array and carry on. If you then switch to a stricter language, you begin to realize how lazy PHP makes you
@haccks: I'm not going to say you shouldn't. If you're coming from C, it'll be easy. Some things will enrage you, some things will be fun... I've often said PHP is a language designed by afterthought and redundancy. functions have just been added on, and added on, seemingly without thought, it's messy. There's also a lot of lazy people writing PHP (too lazy to read even half a page of docs). Those are the bad parts. The fun parts are: it's quick to put together a little script, it can be used properly, and if you write good code, it's easy to read an maintain
|
3

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.

Comments

1

You are passing a single char as a string type(%s) in printf formatted output. Change it to p

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.