首页 > 解决方案 > 为什么修改只读内存是 C/C++ 中未定义的行为?

问题描述

char *s = "hello world". 
s[0] = 'H';

以上是 C/C++ 中未定义的行为。

但这对我来说似乎很明确。您尝试更改只读内存中的某个位置,操作系统说不,这就是它的结束。

但实际上,有时更改会发生,您的字符串实际上会更改。这是如何工作的,为什么这是未定义的?

标签: c++cundefined-behavior

解决方案


以上是 C/C++ 中未定义的行为。

实际上,该程序在 C++11 之前只有 C++ 中的 UB。从 C++11 开始,该程序也是格式错误的(即允许编译器拒绝编译它,并且需要诊断问题)。

但这对我来说似乎很明确。您尝试更改只读内存中的某个位置,操作系统说不,这就是它的结束。

除了没有操作系统时操作系统什么都不说。标准委员会不能简单地决定,因为一个操作系统具有某些行为,所有语言实现——包括那些没有只读内存概念甚至有操作系统的语言实现——都应该具有相同的行为。

但实际上,有时更改会发生,您的字符串实际上会更改。这是如何运作的

简单地说,该语言实现没有将字符串文字存储在只读内存中。它并不比这更复杂。

为什么这是未定义的?

因为语言标准是这样说的。他们这么说是因为委员会如此决定。如果您对他们的基本原理感兴趣,那么您很幸运,因为在这种情况下它已被记录在案

字符串文字被指定为不可修改。该规范允许实现共享具有相同文本的字符串副本,将字符串文字放置在只读内存中,并执行某些优化。但是,字符串文字没有 const char 的类型数组,为了避免指针类型检查的问题,特别是对于库函数,因为将指向 const char 的指针分配给指向 char 的普通指针是无效的。那些坚持字符串文字应该是可修改的委员会成员满足于将这种做法指定为一个公共扩展(参见 F.5.5)。


推荐阅读