C字符串不可变?

根据我的理解,两行代码都创建了6个元素的字符串:

char * output = "AAAAAA" ; char * output [6] ; 

那么,当我试图改变第一个数组字节时,为什么cprogramm在第一个分配情况下崩溃了。 为什么不在第二种情况下崩溃?

 * output = 49; printf("%s\n",output); 

你的理解是错误的。

第一行创建一个指向char的指针,该指针指向字符串“AAAAAA”,该字符串通常存储在可执行文件的不可变数据部分中。 您可以使用非const指针指向它的事实是一个令人遗憾的向后兼容遗留问题。 这就是崩溃的原因。 你应该写:

 const char* output = "AAAAAA"; 

顺便说一句,字符数组有7个元素:’A’的6倍和终结符。

第二行根本不能做你想要的。 它是一个由6个指针组成的数组,使用代码甚至无法编译。 你可能意味着

 char output[6]; 

这是一个由6个字符组成的数组,因此为长度为5的字符串提供空间(仍需要终结符的空间)。 无论如何,这个数组是可变的,所以你可以改变它的元素。

第一个只是一个指针,它被初始化为一个包含你的字符串的不可修改的内存。

第二个是初始化相同数据的数组。

你不能改变指针从第一行指向的数据,但你的数组当然是完全读/写的,就像任何非const数组一样。

将字符串文字视为具有const char *类型。

没有

 char * output [6]; 

创建一个包含六个指向char指针的数组。 即使你使用

 char output [6]; 

你可能意味着什么,这不是一个字符串,而只是一个字符数组。 要使字符数组成为字符串,您必须遵守约定,以确保其中一个字符为0

由于您没有初始化arrays,因此没有这样的保证。

现在,对于您的第一种情况,这实际上不会“创建”新字符串,而是指向字符串文字。 字符串文字实际上不是可变的,并且clang拥有崩溃的所有权利。

第一种情况应该写成const char * output = "AAAAAA" ; 。 编译器在程序的只读部分创建字符串常量,并在其中指向output 。 您可以自由更改output点的位置,但不能随意更改应用程序的只读部分的内容。

C-String数组初始化 – 这是可变的吗?

第一个创建指向字符串文字“hello”的指针,该指针可能存储在程序的可执行映像中的不可写存储器中。 即使不是,也不允许修改该数组的内容。

char*char[]不是一回事。

以下是该标准的含义:

32年6月6日

arrays的内容是可修改的。 另一方面,声明char * p =“abc”; 使用类型”指向char’的指针定义p并初始化它以指向一个类型为”char’数组的对象,其长度为4,其元素用字符串文字初始化。 如果尝试使用p修改数组的内容,则行为未定义。

修改字符串文字的元素会导致未定义的行为“6.4.5字符串文字[#6]”。

PS。 我认为字符串文字被称为只读,这不是C标准中的要求,尽管它在C实现中很常见。 另一个考虑因素是,表示相同字符序列的不同(如lexemes)字符串文字可以对应于单个静态存储持续时间数组。

因为第一个’char * output =“AAAAA”;’ 将输出声明为指向包含字符AAAAA的只读存储区的指针。

然后尝试修改它的第一个字节,这可能是未定义的行为。