4
char* const p = "world";
p[2] = 'l';

第一条语句创建一个由 const 指针 p 指向的字符串,第二条语句尝试修改该字符串,并被编译器接受,而在运行时,弹出访问冲突异常,谁能解释为什么?

4

5 回答 5

3

所以你的问题有两个:

  1. 为什么会出现访问冲突:字符文字字符串作为文字存储在可执行程序的 CODE 页面中;大多数现代操作系统不允许更改这些页面(包括 MS-windows),因此会出现保护错误。

  2. 为什么编译器允许它:这个上下文中的 const 关键字是指指针而不是它指向的东西。代码如 p="Hello"; 将导致编译器错误,因为您已将 p 声明为常量(不是 *p)。如果你想将它指向的东西声明为常量,那么你的声明应该是 const char *p。

于 2013-09-12T13:46:55.243 回答
3

在里面

  char* const p = "World";

P 指向 const 字符数组,它位于 .rodata 内存区域中。因此,不能修改 p 变量指向的数据,也不能将 p 更改为指向其他字符串。

于 2013-09-12T13:51:46.760 回答
1
char* const p = "world";

这在当前的 C++ 标准 (C++11) 中是非法的。大多数编译器仍然接受它,因为它们默认使用以前的 C++ 标准 (C++03),但即使在那里,代码也已弃用,具有正确警告级别的良好编译器应该对此发出警告。

原因是文字的类型"world"char const[6]. 换句话说,文字总是不变的,不能改变。当你说……</p>

char* const p = "world";

…然后编译器文字转换为指针。这是通过称为“数组衰减”的操作隐式完成的:C 数组可以隐式转换为指向其开头的指针。

所以"world"被转换成一个类型的值char const*。请注意const- 我们仍然不允许更改文字,即使通过指针访问也是如此。

唉,C++03 还允许将文字分配给const指针以提供与 C 的向后兼容性。

由于这是一个面试问题,因此正确答案是:代码是非法的,编译器不应该允许它。这是更正后的代码:

char const* const p = "world";
//p[2] = 'l'; // Not allowed!

我们在这里使用了两个 consts:第一个是文字所必需的。第二个使指针本身(而不是指向的值)const

于 2013-09-12T14:23:36.440 回答
0

问题是,如果您定义这样的字符串文字:

char * p = "some text"

编译器将只为指针准备内存,文本位置默认设置为 .text 部分

另一方面,如果您将其定义为:

char p[] = "some text"

编译器会知道您需要整个字符数组的内存。

在第一种情况下,您无法读取该值,因为 MMU 设置为对内存的 .text 部分进行只读访问,在第二种情况下,您可以自由访问和修改内存。

另一个想法(为了防止运行时错误)将是正确描述指针指向的内存。

对于常量指针,它将是:

const char * const p = "blaaaah"

对于普通的:

const char * p = "blaah"
于 2013-09-12T14:01:09.457 回答
-2
char* const p = "world";

这里 p 是一个具有恒定内存地址的指针。因此,这将编译得很好,因为根据编译器没有语法错误,并且它在运行时 bcoz 中引发异常,因为它是一个常量指针,您可以更改它的值。

C++ 引用常量指针

常量正确性

于 2013-09-12T13:54:02.070 回答