为什么我不能写入字符串文字,而我*可以*写入字符串对象?
Why can't I write to a string literal while I *can* write to a string object?
如果我定义如下内容,
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*
。然而,任何优秀的编译器都应该对这种滥用行为发出警告。
相关文章:
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 是否可以在c++中处理字符串流中的各个元素
- 是否可以从格式字符串中检索"width"
- 我可以重新分配/覆盖std::字符串吗
- 有哪些有效的方法可以消除一组 100 万个字符串>重复数据?
- 字符串变量,比如说"字符串str",可以直接复制到数组中吗?
- 是否可以将带有字符串化运算符的宏转换为 constexpr?
- 有人可以解释一下这段代码如何能够反转字符串
- 我可以用字符串变量而不是它的名字创建容器吗? C++
- 我还可以添加什么来按空格或空格正确拆分C++字符串?
- 我可以以相同的方式使用 char* c 和字符串吗?
- 将字符串(可以是十进制字符串或十六进制字符串)转换为整数C++
- 查找字符串可以减少到 0 的步骤数
- Cout 一个字符串可以打印任何内容到屏幕上
- 输入到字符串流并在单个语句中转换为字符串.可以没有帮助程序类
- 正则表达式:从模式字符串 1.string2'string3 中提取字符串,其中字符串 1 可以包含 '." 字符
- 为什么空字符串可以在C++中输出索引 0 元素
- 不能在标准向量中插入自己的结构,但是字符串可以
- std::字符串可以跨DLL边界按值传递吗?
- 输入并存储一个字符串,该字符串可以是用户希望的任何长度