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

Why is the modification of string literal allowed via char*, despite the fact that it points to a read-only memory?

嗯,我最近一直在做很多编程,但我从来没有想过这个简单的问题。 假设我有以下代码片段。

#include <iostream>

int main() 
{
   char* p="hello";
   p[0]='y';
   std::cout<<p;
}

我知道 C++ standard(第 2.14.5 节第 11 段)指出这是未定义的行为。但是,当我仍然想到它时,我就是无法理解这一点。据我所知,字符串文字是在只读内存中分配的,所以当我们声明指向那部分内存的指针时,它是否应该告诉我我不能进行这种类型的转换,但在某些编译器中它只是结束警告,下面的代码仍然编译并打印 yello.

但是,如果我们通过这个小细节修改了上面的代码。

char arr[]="hello"; 

上面的程序对我来说很有意义,因为据我所知,arr 所做的是将字符串复制到堆栈上分配的内存中(如果我错了请纠正我)。

所以我的问题是,除了编译器只知道 p 不是指向 const 的指针这一事实之外,所以它允许修改,它是如何在非常低的级别上允许的handling,上面程序中的OS不应该禁止修改p[0],因为它指向只读内存块吗?

As far as I am aware, string literals are allocated in read-only memory.

那么我建议您 完全 没有意识到的可能性:-)

标准实际上并没有强制字符串文字是只读的,只是试图修改它们是未定义的行为(UB)。

UB 的可能 结果之一是它有时实际上 有效 。当然,这并不意味着它不是一个坏主意,因为它可能随时以任何方式工作或不工作。