C string immutable? [duplicate]

2019-02-05 15:13发布

问题:

This question already has an answer here:

  • Why do I get a segmentation fault when writing to a string initialized with “char *s” but not “char s[]”? 17 answers
  • forbiddens in string literals in C 5 answers
  • Modifying C string constants? [duplicate] 5 answers
  • Simple modification of C strings using pointers 2 answers
  • Defining pointer to static string 3 answers

According to my understanding both lines of code creates string of 6 elements:

char * output = "AAAAAA" ;
char * output [6] ;

So, why cprogramm crashes in first assigment case when I try to chang first array byte. And why not crashes in second case?

* output = 49;
printf("%s\n",output);

回答1:

Your understanding is wrong.

The first line creates a pointer to char which points at the string "AAAAAA", which is usually stored in the immutable data section of your executable. The fact that you can point to it with a non-const pointer is an unfortunate backwards compatibility legacy issue. This is why it crashes. You should write:

const char* output = "AAAAAA";

BTW, the character array there has 7 elements: 6 times the 'A' and a terminator.

The second line doesn't do what you want at all. It's an array of 6 pointers to char, and the usage code doesn't even compile. You probably meant

char output[6];

which is an array of 6 chars and thus offers space for a string of length 5 (still needs space for the terminator). Anyway, this array is mutable, so you can change its elements.



回答2:

The first is just a pointer which is initialized to a non-modifiable piece of memory containing your string.

The second is an array that is initialized the same data.

You cannot change the data pointed at by pointer from the first line, but your array is of course fully read/write like any non-const array would be.

Think of string literals as having the type const char *.



回答3:

No

char * output [6];

creates an array of six pointers to char. Even if you'd use

char output [6];

what you probably meant, this is not a string, but just a character array. For a character array to be a string you have to observe a convention in addition that ensures that one of the characters is 0.

Since you don't initialize the array, there is no such guarantee.

Now for your first case, this actually doesn't "create" a new string, but points to a string literal. String literals are in fact not mutable and clang has all its rights to crash on you.



回答4:

The first case should have been written as const char * output = "AAAAAA" ;. The compiler creates the string constant in a read-only section of the program and points output at it. You're free to change where output points, but not free to change the contents of a read-only section of your application.



回答5:

C-String array initialization - is this mutable?

The first one creates a pointer that points to the string literal "hello", which is probably stored in non-writable memory in the executable image of the program. Even if it isn't, you are not allowed to modify the contents of that array.

char* and char[] are not the same thing.

Here is what the standard has to say about it:

6.6.32

The contents of the arrays are modifiable. On the other hand, the declaration char *p = "abc"; defines p with type ‘‘pointer to char’’ and initializes it to point to an object with type ‘‘array of char’’ with length 4 whose elements are initialized with a character string literal. If an attempt is made to use p to modify the contents of the array,the behavior is undefined.



回答6:

Modifying elements of a string literal results in undefined behaviour "6.4.5 String literals [#6]".

PS. I see string literals mentioned as read-only, this is not a requirement in the C Standard, although it's common across the C implementations. Another consideration is that different (as lexemes) string literals, representing the same sequence of characters, can correspond do a single static storage duration array.



回答7:

Because the first one 'char *output = "AAAAA";' is declaring output as being a pointer to a read only memory area containing the characters AAAAA.

You then try and modify the first byte of this, which is probably undefined behaviour.



标签: c cstring