5

The character pointers in C is confusing me.

Suppose we have a char pointer, which points to the first character of string constant.

char *a="ABCD";

Then we cannot change the value of that character using the pointer a, as following statement results in a segmentation fault.

*a='X';

Now suppose we have a char pointer, which points to a character constant.

const char B='X';    
char *ptr=&B;

Then we are allowed to change the value of that character using the statement

*ptr='Z';

My question is that is this a case of undefined behaviour proving C is not robust? Or is there some deeper logic involved?

Sumeet
  • 8,086
  • 3
  • 25
  • 45
  • @EugeniuRosca you mean `char const *a = "ABCD"`. They don't have the same semantics. – Quentin Jun 19 '15 at 17:26
  • const means that the memory is readonly. Period. You are not allowd to change it by referencing it through another pointer - this should generate a compiler warning. – jim mcnamara Jun 19 '15 at 17:27
  • 1
    Take a look at http://stackoverflow.com/questions/2589949/c-string-literals-where-do-they-go – xp500 Jun 19 '15 at 17:28

3 Answers3

7

Let's say that C lets you shoot yourself in the foot quite easily. Modifying B is still undefined behaviour though, just as modifying *a was, because B has been declared const.

To help with this, turning on warnings (which you should always do unless under very specific circumstances) brings up the following on GCC :

warning: initialization discards 'const' qualifier from pointer
         target type [-Wdiscarded-qualifiers]
Quentin
  • 62,093
  • 7
  • 131
  • 191
5

In C, modification of string literal is not allowed.

char *a="ABCD";  

is equivalent to

char const *a="ABCD";  

*a='X'; is modifying the string literal ABCD. While in second case, ptr is pointing to a character which do not supposed to be changed and *ptr='Z'; will modifying the content of the location that contains X which is also not valid.

Note that modifying a const qualified object is a constraint violation.

haccks
  • 104,019
  • 25
  • 176
  • 264
5

The reason the pointer behaves differently is that C program has several memory segments, some of which are protected.

Then we cannot change the value of that character using the pointer a, as following statement results in a segmentation fault.

Unlike other constants, string constants are placed into a protected segment. Any attempt to modify this segment results in undefined behavior (i.e. your program could segfault).

Since your pointer points into a string constant, the value to which it points cannot be modified. If you force a copy of the constant into modifiable memory by using an array, the same modification would be allowed:

char a[]="ABCD";
*a='X';

Then we are allowed to change the value of that [single] character using the statement

This is because character constant is always copied into modifiable memory.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523