0
#include<stdio.h>
#include<string.h>

int main()
{
    int i, n;
    char *x="Alice"; // ....... 1
    n = strlen(x);   // ....... 2
    *x = x[n];       // ....... 3
    for(i=0; i<=n; i++)
    {
        printf("%s ", x);
        x++;
    }
    printf("\n");
    return 0;
}

String constant cannot be modified. In the above code *x means 'A'. In line 3 we are trying to modify a string constant. Is it correct to write that statement? When I run this code on Linux, I got segmentation fault. But on www.indiabix.com, they have given answer:

If you compile and execute this program in windows platform with Turbo C, it will give lice ice ce e It may give different output in other platforms (depends upon compiler and machine). The online C compiler given in this site will give Alice lice ice ce e as output (it runs on Linux platform).

Jhansi Rani
  • 449
  • 1
  • 5
  • 11
  • What book is that? Do they actually modify like you have? Because the answer you posted from the book suggests they are just moving the pointer and printing it. And irrespective what the book says, modifying string literal is not allowed and doing so results in *undefined behaviour*. – P.P Nov 30 '14 at 09:44
  • @BlueMoon The answer suggests that they do set `*x` to `'\0'` (`x[n] == '\0'`): without that, a compiler couldn't give "lice ice ce e" as output. –  Nov 30 '14 at 09:45
  • If you think any of the posts below answer your question, please accept it by click check sign next to it. This will make the answer float to the top and award some reputation points to you and the answerer. – Mohit Jain Apr 10 '15 at 07:25

4 Answers4

3

Your analysis is correct. The line

*x = x[n];

is trying to modify a string literal, so it's undefined behavior.


BTW, I checked the website that you linked. Just browsing it for two minutes, I've already found multiple incorrect code samples (to name a few, using gets, using char(not int) to assign return value of getchar, etc), so my suggestion is don't use it.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • Could you give me any website link or any book to practice problems on C. I am practicing in that website because I don't have any other option. @Yu Hao – Jhansi Rani Nov 30 '14 at 10:23
  • @JhansiRani, Try to read some books.. `The C programming Language` or `Let us C` is my choices.. – Raghuveer Dec 03 '14 at 07:02
3

Your analysis is correct, but doesn't contradict what you quoted.

The code is broken. The answer already acknowledges that it may behave differently on different implementations, and has given two different outputs by two different implementations. You happen to have found an implementation that behaves in a third way. That's perfectly fine.

0

In this code, the memory for "Alice" will be in the read-only data section of the executable file and x is a pointer pointing to that read-only location. When we try to modify the read-only data section, it should not allow this. But char *x="Alice"; is telling the compiler that x is declared as a pointer to a character, i.e. x is pointing to a character which can be modified (i.e. is not read-only). So the compiler will think that it can be modified. Thus the line *x = x[n]; will behave differently on different compilers. So it will be undefined behavior.
The correct way of declaring a pointer to a assign string literal is as below:

const char *x ="Alice";

Only then can the behavior of the compiler be predicted.

Yun
  • 3,056
  • 6
  • 9
  • 28
Jhansi Rani
  • 449
  • 1
  • 5
  • 11
0

Modification of a string literal is Undefined Behaviour. So the behaviour you observe, and the two described, are consistent with the requirements of the C standard (as is emailing your boss and your spouse, or making demons fly out of your nose). Those three are all actually quite reasonable actions (modify the 'constant', ignore the write, or signal an error).

With GCC, you can ask to be warned when you assign the address of a string literal to a pointer to (writable) char:

cc -g -Wall -Wextra -Wwrite-strings   -c -o 27211884.o 27211884.c
27211884.c: In function ‘main’:
27211884.c:7:13: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default]
     char *x="Alice"; // ....... 1
             ^

This warning is on by default when compiling C++, but not for C, because char* is often used for string literals in old codebases. I recommend using it when writing new code.

There are two correct ways to write the code of the example, depending on whether you want your string to actually be constant or not:

const char *x = "Alice";
char x[] = "Alice";
Toby Speight
  • 27,591
  • 48
  • 66
  • 103