char* const p = "world";
p[2] = 'l';
第一个语句创建一个由const指针p指向的字符串,第二个语句尝试修改字符串,并且它被编译器接受,而在运行时,一个访问冲突异常是poped,并且任何人都可以解释原因?
答案 0 :(得分:3)
所以你的问题是双重的:
为什么会出现访问冲突:字符文字字符串作为文字存储在可执行程序的CODE页面中;大多数现代操作系统不允许更改这些页面(包括MS-windows),从而保护故障。
为什么编译器允许它:这个上下文中的const关键字指的是指针,而不是指向它的东西。代码如p =“Hello”;您将p声明为常量(而不是* p)会导致编译器错误。如果你想声明它指向的东西,那么你的声明应该是const char * p。
答案 1 :(得分:3)
在
中 char* const p = "World";
P指向const字符数组,它位于.rodata内存区域。因此,不能修改p变量指向的数据,也不能将p更改为指向其他字符串。
答案 2 :(得分:1)
char* const p = "world";
这在当前的C ++标准(C ++ 11)中是非法的。大多数编译器仍然接受它,因为它们默认使用以前的C ++标准(C ++ 03),但即使代码是已弃用,并且具有正确警告级别的良好编译器应该警告这一点。
原因是文字"world"
的类型是char const[6]
。换句话说,文字总是常量且无法更改。当你说...
char* const p = "world";
...然后编译器将文字转换为指针。这是通过一个名为“array decay”的操作隐式完成的:C数组可以隐式转换为指向其开头的指针。
因此"world"
转换为char const*
类型的值。请注意const
- 即使通过指针访问,我们仍然不允许更改文字。
唉,C ++ 03还允许将文字分配给非 - const
指针,以提供与C的向后兼容性。
由于这是一个面试问题,因此正确的答案是:代码是非法的,编译器不应该允许它。这是更正后的代码:
char const* const p = "world";
//p[2] = 'l'; // Not allowed!
我们在这里使用了两个 const
:第一个是文字所必需的。第二个使指针本身(而不是指向的值)const
。
答案 3 :(得分:0)
如果你定义一个像这样的字符串文字:
char * p = "some text"
编译器将仅为指针和文本位置准备内存 默认设置为.text section
另一方面,如果你把它定义为:char p[] = "some text"
编译器会知道你想要整个字符数组的内存。
在第一种情况下,您无法读取该值,因为MMU设置为只读取内存的.text部分,在第二种情况下,您可以自由访问和修改内存。
另一种想法(防止运行时错误)将正确描述指针指向的内存。
对于常量指针,它将是:
const char * const p = "blaaaah"
和正常的:
const char * p = "blaah"
答案 4 :(得分:-2)
char* const p = "world";
这里p是一个具有恒定存储器地址的指针。所以这将编译正常,因为根据编译器没有语法错误,并且它在运行时bcoz中抛出异常,因为它是一个常量指针,你可以改变它的值。