1
#include<stdio.h>
 int main(void)
 {
   char s='a',*j;
   j=&s;
   *j='b';
   printf("s is %c",s);
 }

Output: s is b.

From This program we get that we can change the values assigned to constant char by changing the value of the pointer.

But this doesnt happen with the following program.

#include<stdio.h>
int main(void)
{
  char *p="Hello";
  *p='z';   //By assuming that it should change 'H' as *p points to address of H//
  printf("%c",*p);
}

Output: Segmentation Fault Core dumped

Shouldnt even in this case the value of the 0th char in the Hello change as we are manipulating its pointer,doesnt *p point to the value at address of H.Shouldnt the output expected here be "zello".

  • you are trying to change a string literal. This has a long history. IN many older c compilers this was wrongly allowed. some compilers will still allow it for backwards compatibility reasons. But clearly yours does not – pm100 Jan 25 '18 at 19:26

1 Answers1

4

From This program we get that we can change the values assigned to constant char by changing the value of the pointer.

There is no "constant char" in your first snippet. It is just a variable of type char initialized with some value. It is allocated in RW memory, so you can take it's address and modify the content.

In the second snippet you define a pointer and assign it with an address of a string literal, which is allocated in a memory which is not supposed to be written (often it is read only, or it's just an undefined behavior writing to it).

Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61
  • +1 I have even seen it work occasionally, so it can be very unpredictable. I would assume literals get put in the .data section and probably should be read-only, but I guess optimizing compilers might decide otherwise. – Patrick87 Jan 25 '18 at 19:27
  • 1
    @Patrick87 I would imagine they are put into `.rodata`. But it might not be enforced as read-only. Also I believe there are extensions making string literals writable. But the UB can arise from different other things, such as having only one "Hello" allocated for initializing different pointers and/or passing this literal to functions. So modifying it in one place would lead to some very funny stuff. – Eugene Sh. Jan 25 '18 at 19:29
  • whats the actual difference between a string literal and array of chars? – Devashish Dewalkar Jan 25 '18 at 19:51
  • @DevashishDewalkar You can think of string literal as an array of chars located in read-only memory. Also take a look at a [question](https://stackoverflow.com/questions/30533439/string-literals-vs-array-of-char-when-initializing-a-pointer) I asked when I was younger :) – Eugene Sh. Jan 25 '18 at 20:06
  • @EugeneSh. the memory for the string literal is created in the `.rodata` section of the executable and is read-only (just for a verbiage clarification) Which you can confirm with a `gcc -S -masm=intel -o file.asm file.c` and you will find `.section .rodata` just prior to `.string "Hello"` – David C. Rankin Jan 25 '18 at 21:41
  • @DavidC.Rankin What I meant by "not enforced" is that the memory might be still mapped by the OS/MMU as writable, so it won't generate apparent access violations.. – Eugene Sh. Jan 25 '18 at 21:45
  • Oh, my comment was a compliment, not a criticism. Sorry if you took it differently. – David C. Rankin Jan 25 '18 at 21:47