修改char*const字符串

Kod*_*rok 2 c c++ string pointers runtime-error

我知道这const char *是一个指向const char的指针,而是一个指向char char *const的常量指针.我在以下代码中测试它:

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?    
Run Code Online (Sandbox Code Playgroud)

最后一行不会给出任何错误,但会导致程序意外终止.为什么要修改t不允许指向的字符串?

Sha*_*our 7

t指向字符串文字,修改字符串文字是未定义的行为.C++草案标准部分2.14.5 字符串文字12段说(强调我的):

是否所有字符串文字都是不同的(即存储在非重叠对象中)是实现定义的.尝试修改字符串文字的效果是未定义的.

C99标准草案的相关部分是6.4.5 字符串文字6段,其中说明(强调我的):

如果这些数组的元素具有适当的值,则这些数组是否不同是未指定的.如果程序试图修改此类数组,则行为未定义.

在典型的现代Unix平台上,您将在只读段中找到字符串文字,如果我们尝试修改它,将导致访问冲突.我们可以使用objdump来检查只读部分,如下所示:

objdump -s -j .rodata
Run Code Online (Sandbox Code Playgroud)

我们可以在下面的实例中看到,字符串文字确实可以在只读部分中找到.请注意,我必须添加一个printf否则编译器将优化字符串文字.示例` objdump输出:

Contents of section .rodata:
 400668 01000200 776f726c 64002573 0a00      ....world.%s..
Run Code Online (Sandbox Code Playgroud)

另一种方法是t指向一个带有字符串文字副本的数组,如下所示:

char r[] = "world";    
char *const t = r ;
Run Code Online (Sandbox Code Playgroud)