【问题标题】:Why can't I write to a string literal while I *can* write to a string object?为什么我不能写入一个字符串文字,而我*可以写入字符串对象?
【发布时间】:2012-02-01 20:59:42
【问题描述】:

如果我定义如下内容,

char  *s1 = "Hello";

为什么我不能像下面那样做,

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

如果我执行以下操作会怎样,

string s1 = "hello";

我可以像下面那样做吗,

*s1 = 'w'; 

【问题讨论】:

标签: c++ string stl


【解决方案1】:

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

const char* s1 = "Hello";

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 是的,但将对话限制在 C++ 定义的抽象机器的范围内会更有帮助。它已经竭尽全力确保字符串文字被视为常量数据;没有必要谈论使这成为有用/安全选择的物理现实,特别是因为这些现实在世界各地使用的各种物理实现中的实际准确性可能会随着时间的推移而变化。
    【解决方案3】:

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

    但是当你这样做时

    string s1 = "hello";
    

    您将 const char* "hello" 复制到 s1。区别在于第一个示例 s1 指向只读“hello”,而在第二个示例中,只读“hello”复制到非常量 @ 987654327@,允许您访问复制的字符串中的元素以对它们做您想做的事情。

    如果你想对 char* 做同样的事情,你需要为 char 数据分配空间并将 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”的类型不是 char const* (或 const char*,如果你坚持的话),而是 char const[6] 在第一次机会时衰减为 char const* (或者,接受分配给 char*)。
    【解决方案4】:

    是时候混淆视听了:

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

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

    【讨论】:

      猜你喜欢
      • 2020-10-15
      • 2018-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-25
      • 2014-03-04
      • 1970-01-01
      • 2010-10-31
      相关资源
      最近更新 更多