char *p = "string literal"; p[0] = 'S';
char a[] = "string literal"; a[0] = 'S';
这两者之间的主要区别是什么?
当这两个被定义时,内存中到底发生了什么?
为什么修改第一个会导致未定义的行为?
我在某处读到第一个可能存储在只读存储器中的地方;我的问题是:这是怎么发生的?
p
指向不应修改的字符串文字;a
是一个可以修改的字符数组。重要的是要认识到该标准只是说“您不得修改字符串文字”(或多或少),并且尝试这样做可能会导致任何效果。您的程序可能会崩溃(分段违规或等效);您的代码可能会修改文字;您的代码可能既不会崩溃也不会更改文字。请注意,如果程序中有多个地方出现文字,则修改一个可能会修改所有地方——编译器允许字符串文字共享内存中的空间。它们甚至不必完全相同。"string literal"
并且"literal"
可以是指向内存中同一字符串的不同部分的指针。
ISO/IEC 9899:2011,§6.4.5字符串文字说:
¶6 在翻译阶段 7 中,将一个字节或零值代码附加到每个由一个或多个字符串文字产生的多字节字符序列。然后使用多字节字符序列来初始化一个静态存储持续时间和长度刚好足以包含该序列的数组。[...]
¶7 如果这些数组的元素具有适当的值,则未指定这些数组是否不同。如果程序尝试修改这样的数组,则行为未定义。