Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
341 views
in Technique[技术] by (71.8m points)

c++ - Modifying a char *const string

I know that const char * is a pointer to a const char, while char *const is a constant pointer to a char. I am testing this in the following code:

const char *s = "hello";    // Not permitted to modify the string "hello"
char *const t = "world";    // Not permitted to modify the pointer t

s = "hello2";   // Valid
// t = "world2";   // Invalid, gives compilation error

// *(s + 1) = 'a';    // Invalid, gives compilation error
*(t + 1) = 'a';       // Why does this not work?    

The last line does not give any error, but causes the program to terminate unexpectedly. Why is modifying the string pointed to by t not allowed?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

t is pointing to a string literal it is undefined behavior to modify a string literal. The C++ draft standard section 2.14.5 String literals paragraph 12 says(emphasis mine):

Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation defined. The effect of attempting to modify a string literal is undefined.

The relevant section from the C99 draft standard is 6.4.5 String literals paragraph 6 which says(emphasis mine):

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

On a typical modern Unix platform you will find string literals in the read-only segment which would result in a access violation if we attempt to modify it. We can use objdump to inspect the read-only section as follows:

objdump -s -j .rodata

we can see in the following live example that the string literal will indeed be found in the read-only section. Note that I had to add a printf otherwise the compiler would optimize out the string literal. Sample `objdump output:

Contents of section .rodata:
 400668 01000200 776f726c 64002573 0a00      ....world.%s..

An alternative approach would be to have t point to an array with a copy of a string literal like so:

char r[] = "world";    
char *const t = r ;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...