You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ std::string索引时s[i]运行正常但s.at(i)抛出异常的原因是什么?

问题结论

首先明确:你当前场景中[]运算符的行为在C++11及之后的标准中是明确定义的合法行为,不属于未定义行为,at()抛出异常是二者的设计规则差异导致的。

规则差异说明

C++标准对std::string的下标访问方法有明确的不同约束:

  • operator[](size_t pos)的规则:
    • 当pos < size()时,返回对应位置字符的引用,行为合法。
    • 当pos == size()时:
      • 针对const修饰的std::string实例,返回值为'\0'的常量字符引用,读操作是合法的。
      • 针对非const实例,仅允许读该位置的'\0',如果修改该位置的值会触发未定义行为。
    • 只有当pos > size()时,才会触发未定义行为。
  • at(size_t pos)的规则:
    只要访问位置pos >= size(),无论是什么场景,都会直接抛出std::out_of_range异常,不存在例外情况。
代码问题根因

你的循环终止条件是直接判断访问到的字符是否为'\0',处理无内嵌nul的字符串(比如示例中的"item2"s,size()为5)时:

  1. 用[]访问时,i=5等于size(),合法返回'\0',循环正常终止。
  2. 用at()访问时,i=5满足pos >= size()的抛异常条件,直接触发越界异常。
修复方案

调整循环条件,先判断下标是否在合法范围内,再判断字符是否为nul即可,修改后的循环代码如下:

for (const string& s : vs)
{
    for (int i = 0; i < s.size() && s.at(i); i++)
        cout << s.at(i);
    cout << "\n";
}

这样就能避免访问到pos == size()的位置,不会触发at()的越界异常,同时保留边界检查的能力。

内容的提问来源于stack exchange,提问作者doug

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 01:27:03