-4

Why am I'm getting this error "Segmentation fault (core dumped)" while running this program, what is wrong with it?

#include <stdio.h>

int main() {

    char *p = "Sanfoundry C-Test";

    p[0] = 'a';

    p[1] = 'b';

    printf("%s", p);

    return 0;
}
Klesun
  • 12,280
  • 5
  • 59
  • 52
Never Back Down
  • 138
  • 2
  • 12
  • 10
    It behaves undefined. – πάντα ῥεῖ Jun 28 '14 at 12:43
  • With proper optimization, I'll bet you it prints "Sanfoundry C-Test". Not that you can count on that at all. Also worth noting this is a compiler error in C++11. – chris Jun 28 '14 at 12:43
  • 1
    Enable all warnings, and read them out loud / then you will see what this about / The literal is constant, and source of your failure / that's why you end up in undefined behaviour: `"deprecated conversion from string constant to 'char*'"`. – Zeta Jun 28 '14 at 12:49
  • On the Mac with compiler `Apple LLVM version 5.1 (clang-503.0.40)` it gives a `Bus Error`. – vacawama Jun 28 '14 at 12:51
  • It's good habit (at least) to always use pointers to `const char` if dealing with string literals: `const char *p = "San...";` – mafso Jun 28 '14 at 12:54
  • Ah, it's "String Literal Saturday" again. My second most dreaded day in the year, just after Arbor Day. – Kerrek SB Jun 28 '14 at 12:55
  • -1 not the real code (`main` must have a function return type). – Cheers and hth. - Alf Jun 28 '14 at 12:57
  • Re my -1 comment: C99 §5.1.2.2.1/1 "It shall be defined with a return type of `int`". But testing this I find that both msvc and gcc incorrectly and very sloppily compiles your code, so that the code is possibly real. I still choose to keep the downvote because presenting such code is very ungood, teaching bad habits to readers. – Cheers and hth. - Alf Jun 28 '14 at 13:04
  • Cheers and nth. - Alf, the `Apple LLVM version 5.1 (clang-503.0.40)` compiler requires `int main`. – vacawama Jun 28 '14 at 13:07
  • @Cheersandhth.-Alf: `gcc` doesn't compile in C99 mode by default; compiling with `-std=c99 -pedantic`, gcc yields a warning. There's nothing “sloppy” about this. Anyway, the question is updated… – mafso Jun 28 '14 at 13:34

3 Answers3

6

String literals are unmodifiable in C:

char *p = "Sanfoundry C-Test";
p[0] = 'a';

The last statement invokes undefined behavior.

Use a character array initialized with a string literal to have a defined behavior:

char p[] = "Sanfoundry C-Test";
p[0] = 'a';
ouah
  • 142,963
  • 15
  • 272
  • 331
  • Four of the most likely `undefined behaviors` are (in no particular order): 1) compiler warning, 2) SEGFAULT/Bus Error, 3) the string is unmodified, 4) it appears to work as intended and the string is modified (the worst outcome of all, really). – vacawama Jun 28 '14 at 13:12
  • 5) it starts formatting your hard disk (not sure how likely that is, though). ;-) – Rudy Velthuis Jun 28 '14 at 22:37
1

As others have said, that should not be done that way, since you are modifying something that is supposed to be (and often is) unmodifiable.

char *p = "Sanfoundry C-Test";

This declares a pointer and points it to (sets the address contained in the pointer to the start of) the literal text (which is constant and should not be modified and probably can't be modified without an error anyway) "Sanfoundry C-Test".

But AFAIK, you are asking what the rest of the code means, so let's first correct the problem:

char p[] = "Sanfoundry C-Test";

That declares an array of char with the given contents (the characters 'S', 'a', 'n', etc., followed by a 0 character). Such an array is treated as a text string, by C. Now

p[0] = 'a';

Changes the first character of that array (arrays "start counting" at 0), so the 'S' in the string is changed to an 'a'.

p[1] = 'b';

This changes the second character into 'b'. So now the string is "abnfoundry C-Test". The final printf() then displays that value in a console.

Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
0

This is the difference between a char array and a char pointer.

char p[]="Sanfoundry C-Test";

Then you can do

p[0]='a';
p[1]='b';

But you cannot do it if p is a pointer which is in your case.

For more information, see the link provided below

What is the difference between char s[] and char *s?

Community
  • 1
  • 1
Ayush
  • 2,608
  • 2
  • 22
  • 31
  • 1
    Your answer is way too misleading imo. Of course you can modify strings through pointers. In fact, in your example, `p` decays to a pointer in order for the indexing to work. The difference here is that the array *copies* the string so you can actually modify that memory. – chris Jun 28 '14 at 12:46
  • It's not really about the difference between arrays and pointers. OP could very well have done `char *p = (char []){ "Sanf..." };` and would still be dealing with pointers. On the other hand, using an array of `const char`s and writing to them (after casting `const` away) would be UB. – mafso Jun 28 '14 at 12:48
  • @mafso, Forgive my lack of C knowledge, but would `(char[]){"…"}` not create a temporary `char[]` that is destroyed right away, leaving `p` dangling? – chris Jun 28 '14 at 12:53
  • The lifetime of the created object would be that of the enclosing block. Yes, this is a difference to string literals, but your suggestion (`char p[] = "..."`) has exactly the same lifetime. But that wasn't my point anyway. OP's problem actually has nothing to do with the pointer/array difference; just because you offer a solution involving an array doesn't make it an array/pointer problem. It's solely about string literals not being modifiable. – mafso Jun 28 '14 at 13:00