【问题标题】:Access any position in C++ empty string访问 C++ 空字符串中的任何位置
【发布时间】:2023-03-16 12:00:02
【问题描述】:

为什么C++空字符串可以在任意位置访问而不会出错?

例如,

string str(""); 

str[1], str[2] 只会返回空。

为什么下面的语句没有报错?

str[2] = 'a'

但是,打印出str 仍然显示空字符串。

我在这里很困惑,可能错过了一些东西。

【问题讨论】:

  • 你用的是什么编译器?因为当我尝试分配std::string str("") str[2] = 'a'时我的爆炸了
  • 它可以返回空,但也可以格式化您的硬盘。
  • 您所缺少的只是这是 Undefined Behaviour,C++ 不能保护您免受 Undefined Behaviour 的影响,而且它通常更好避免 UB 而不是试图猜测给定编译器将选择哪种特定的不可预测的故障机制。
  • 非常感谢。非常有用的答案。

标签: c++ string


【解决方案1】:

访问超出范围的下标是未定义的。对于空的std::string,使用任何下标都是非法的。

但是,库不需要检查下标的值。确保下标合法的工作留给了程序员,也就是你。

【讨论】:

    【解决方案2】:

    字符串是(某种意义上)你可以插入东西的字符数组。当你把它设为 "" 时,它保证 至少 0 个字符的长度是可用的。当您将某些内容分配给角色 [2] 时,行为是未定义的,并且它有权爆炸,但很有可能它会大到足以在不注意的情况下吸收您的错误......

    【讨论】:

    • 很有可能如果它真的爆炸了,它会在完全出乎意料的地方爆炸,而且显然根本没有连接到字符串。
    【解决方案3】:

    std::string 元素可以使用[] 运算符和at() 函数访问。运算符不需要执行边界检查,就像 C++ 中的常规数组访问一样,而函数会抛出 out_of_range 来处理无效索引。

    【讨论】:

      【解决方案4】:

      除了 Yu 和 Andy 的答案当然是正确的之外,我想向您指出 string::at,与 string::operator[] 不同,它会进行边界检查,如果您尝试超出范围,则会通过异常- 边界访问:

      #include <string>
      int main()
      {
          std::string s("");
          return s.at(1);
      }
      

      输出:

      terminate called after throwing an instance of 'std::out_of_range'
        what():  basic_string::at
      Aborted (core dumped)
      

      【讨论】:

        猜你喜欢
        • 2014-05-12
        • 1970-01-01
        • 2018-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多