1
int main(void) {
    char *p = "hello";
    char *q = "world";
    *p = *q;
    printf("%s", *p);
}

I am trying to overwrite hello with world...

Nifle
  • 11,745
  • 10
  • 75
  • 100
user133466
  • 3,391
  • 18
  • 63
  • 92

7 Answers7

11

Attempting to modify a string literal results in undefined behavior. For example, some implementations will store that string in a read-only section of memory. You cannot (and should not try) to overwrite that memory.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • 1
    And it's a misfeature of C (for legacy reasons) that string literals have type `char *` instead of `const char *`. – Steve Jessop Nov 05 '09 at 02:54
  • They are **not** guaranteed to be read-only, its implementation defined. Many older compilers make string literals mutable. – Richard J. Ross III Nov 28 '12 at 07:34
  • @RichardJ.RossIII: Thanks. I know that now, but I was less informed in 2009 when I wrote this answer. Modifying a string literal simply results in UB, I'll update my answer. – Ed S. Nov 28 '12 at 19:42
11

You're just overwriting the first character of hello, i.e. h with the first character of world, i.e. w.

Also, if you want to stick with your original code,

p = q;
printf("%s", p);

Also, with p = q you are not overwriting anything. p now points to the first character of world.

As Ed said, you cannot overwrite the data stored in p with the data in q.

Community
  • 1
  • 1
Jacob
  • 34,255
  • 14
  • 110
  • 165
5

This line:

*p = *q;

Will set the char (singular) pointed to by p to the char pointed to by q.

You want strncpy if you want to copy strings. (Although see Ed's comment about the read-only nature of the strings in your code).

geofftnz
  • 9,954
  • 2
  • 42
  • 50
  • 2
    For the record, `*cpy()` functions won't help here because the data is stored in read-only memory. But +1 for explaining the error in his logic. – Chris Lutz Nov 05 '09 at 02:19
  • Correct - I made the assumption that it was a basic pointer question. (Initially I didn't see the data section problem - C# has made me soft) – geofftnz Nov 05 '09 at 22:39
2

Firstly, your code only tries to overwrite the first character of "Hello" with first character of "World", i.e. it attempts to turn "Hello" into "Wello".

Secondly, you are trying to modify a string literal. Sitring litrerals are not modifiable. You can't "overwrite" string literal. Your attempt to overwrite "Hello" with "World" is not much different from an attempt to overwrite 5 with 8 by doing 5 = 8.

For further reading see Why is this string reversal C code causing a segmentation fault?

Thirdly, in order to print a string with printf you have to pass a pointer to the first character, not the first character itself. Your printf should look as printf("%s", p)

Community
  • 1
  • 1
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

You are not passing the address of the pointer if you want to print the "world" then you need to pass the address of the string world to the pointer "hello" this is achieved by writing p=q;.

Problem solved. The rest of the code is correct.

Himanshu
  • 31,810
  • 31
  • 111
  • 133
0

char *p = "hello"; char *q = "world"; the both variables are constant, unchangeable

StevenWang
  • 3,625
  • 4
  • 30
  • 40
  • That's not true. The variables are not const, what they point to is. – Ed S. Nov 05 '09 at 02:21
  • Even that is not true. String literals in C are not constant (by type). They are simply non-modifiable. This is not exactly the same thing. – AnT stands with Russia Nov 05 '09 at 02:23
  • I meant the content p and q refer is constant, you cannot change the content – StevenWang Nov 05 '09 at 03:20
  • but you say that 'both *variables* are const', which is semantically meaningful in C. @Andrey: Yes, I was thinking more conceptually, but I should have said that they point to readonly memory. – Ed S. Nov 05 '09 at 04:02
0

Both are L values so can't b changed..... leads to Segmentation Fault or any Runtime Logical error

so it is safe to use

p=q;

as now p starts pointing to the string to which q is pointing

Jérôme Verstrynge
  • 57,710
  • 92
  • 283
  • 453
Anshul garg
  • 233
  • 2
  • 6