为什么允许通过char*修改字符串文字,尽管它指向只读内存?



我最近一直在做很多编程工作,但是这个简单的问题从来没有在我脑海中闪过。假设我有以下代码片段:

#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的可能的结果之一是它有时实际上起作用。当然,这并不能使它成为一个坏主意,因为它可能在任何时候以任何方式工作或不工作。

最新更新