5
include<stdio.h>
int main()
{
    //char b[10];
    char *a="goodone";
    //a=b;

    scanf("%s",a);//this scanf fails and thow segmentation fault.
    printf("%s",a);

} 

Why is this not working? I tried a lot with this scanf but, when I reserve memory for my variable a*(by assigning a=b (commented)) it works fine. Otherwise it doesn't. I believe that char *a will allocate some memory for its string,("goodone")and return that memory location to its value. And printf working fine with this belief why scanf not? please save me from this....

Jens
  • 69,818
  • 15
  • 125
  • 179
vimalpt
  • 551
  • 3
  • 16
  • I strongly recommend to read the [C FAQ entry](http://c-faq.com/aryptr/aryptr2.html) for this question. – Lundin Feb 15 '12 at 10:56
  • This is definitely a good read: [What is the difference between char a\[\] = “string”; and char *p = “string”;](http://stackoverflow.com/questions/9460260/what-is-the-difference-between-char-a-string-and-char-p-string) – Alok Save May 29 '12 at 09:32

2 Answers2

2

This is because you are instructing scanf to write the data that it reads into the memory allocated for the const char* value, i.e. into read-only memory.

If you would like to make your string constant writable, change

char *a="goodone";

to

char a[]="goodone";

Note that this is not safe either: it may crash when the user enters more than seven characters. Add a limit to your format specifier in order to address that issue:

scanf("%7s",a);

P.S. The commented out a=b works fine because it is not modifying the string constant; rather, it modifies a pointer to character constant, which is allowed.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 2
    To emphasize the point, *never* use `scanf()` with a bare `%s` format. No matter how big a buffer you provide, you cannot prevent the user from entering enough characters to overflow it. It's as unsafe as `gets()` (which also should never be used). – Keith Thompson Feb 15 '12 at 10:19
  • @KeithThompson gets() is no longer standard C, since C11. – Lundin Feb 15 '12 at 10:58
  • @Lundin: Right -- but most or all implementations still provide it (perhaps with a warning), and sadly there are still plenty of books and tutorials that use it. – Keith Thompson Feb 15 '12 at 23:52
1

char *a is just a pointer to a char. When you assign "goodone" to it, it points to that string literal (which is read-only), and scanf tries to overwrite that string in memory which causes the crash.

If you assign b to it, then you have a pointing to a writeable memory area of 10 chars (i.e., a string of maximum length 9 + the terminating NUL). So it works as long as scanf is not storing anything longer than that in there.

Likewise you could make a an array instead of a pointer (i.e., char a[] = "goodone";). Again you need to watch out not to store anything longer in there.

Arkku
  • 41,011
  • 10
  • 62
  • 84