修改 char *const 字符串

2021-12-13 00:00:00 string pointers c runtime-error c++

我知道const char * 是一个指向const char 的指针,而char *const 是一个指向char 的常量指针.我正在以下代码中对此进行测试:

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?    

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

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?

推荐答案

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

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.

C99 草案标准的相关部分是 6.4.5 String literals 段落 6 说(强调我的em>):

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.

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

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

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

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..

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

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 ;

相关文章