为什么我不能写入字符串文字,而我*可以*写入字符串对象?

Why can't I write to a string literal while I *can* write to a string object?

本文关键字:字符串 可以 对象 而我 文字 不能 为什么      更新时间:2023-10-16

如果我定义如下内容,

char  *s1 = "Hello";

为什么我不能做下面这样的事情,

*s1 = 'w'; // gives segmentation fault ...why???

如果我做下面这样的事情呢,

string s1 = "hello";

,我能做下面这样的事情吗

*s1 = 'w'; 

因为"Hello"创建了一个const char[]。这衰减为const char*而不是char*。在C++中,字符串文字是只读的。你已经创建了一个指向这样一个文字的指针,并试图对其进行写入。

但当你做时

string s1 = "hello";

将const char*"hello"复制到s1中。第一个示例中的区别是s1指向只读"hello",而在第二个示例中,只读"hello"被复制到非常量s1中,允许您访问复制字符串中的元素,以便对它们执行所需操作。

如果你想对一个字符做同样的事情,你需要为字符数据分配空间,并将hello复制到中

char hello[] = "hello"; // creates a char array big enough to hold "hello"
hello[0] = 'w';           //  writes to the 0th char in the array

字符串文字通常分配在只读数据段中。

因为Hello驻留在只读存储器中。你的签名实际上应该是

const char* s1 = "Hello";

如果您想要一个可变缓冲区,那么将s1声明为char[]std::string重载operator [],因此可以对其进行索引,即s1[index] = 'w'

混淆问题的时间:

char s0[] = "Hello";
s0[0] = 'w';

这是完全有效的!当然,这并不能回答最初的问题,所以我们开始:字符串文字是在只读内存中创建的。也就是说,它们的类型是char const[n],其中n是字符串的大小(包括终止的null字符,即字符串字面"Hello"n == 6。但是,为什么,哦,为什么这个类型可以用于初始化char const*?答案只是向后兼容性,分别与[旧]兼容C代码:当const进入该语言时,许多地方已经用字符串文字初始化了char*。然而,任何优秀的编译器都应该对这种滥用行为发出警告。