我最近一直在做很多编程工作,但是这个简单的问题从来没有在我脑海中闪过。假设我有以下代码片段:
#include <iostream>
int main()
{
char* p="hello";
p[0]='y';
std::cout<<p;
}
我知道c++标准(第2.14.5节第11段)声明这是一个未定义的行为。然而,当我还在想这件事的时候,我就是不能理解这一点。据我所知,字符串字面值是在只读内存中分配的,所以当我们声明指向该部分内存的指针时,它应该告诉我不能进行这种类型的转换,但在一些编译器中,它只是以警告结束,下面的代码仍然编译并打印yello
。
但是,如果我们通过这个小细节修改了上面的代码。
char arr[]="hello";
上面的程序对我来说是有意义的,因为据我所知,arr所做的是将字符串复制到堆栈上分配的内存中(如果我错了请纠正我)。
所以我的问题是,除了编译器只知道p
不是指向const的指针这一事实,所以它允许修改,它是如何允许在非常低级别的处理中,操作系统不应该禁止在上面的程序中修改p[0]
,因为它指向一个只读内存块?
据我所知,字符串字量是在只读内存中分配的。
那么我建议你可能没有完全意识到:-)
标准实际上并没有要求字符串字面值是只读的,只是试图修改它们是未定义行为(UB)。
UB的可能的结果之一是它有时实际上起作用。当然,这并不能使它成为一个坏主意,因为它可能在任何时候以任何方式工作或不工作。