为什么允许通过 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 的可能 结果之一是它有时实际上 有效 。当然,这并不意味着它不是一个坏主意,因为它可能随时以任何方式工作或不工作。
嗯,我最近一直在做很多编程,但我从来没有想过这个简单的问题。 假设我有以下代码片段。
#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 的可能 结果之一是它有时实际上 有效 。当然,这并不意味着它不是一个坏主意,因为它可能随时以任何方式工作或不工作。