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

C++中向string插入字符时[]下标运算符与push_back方法的区别

C++空string用[]下标赋值失效的根本原因

核心是对std::string的下标运算符行为存在认知偏差:

  • operator[]的设计逻辑是仅访问字符串有效长度范围内的已存在元素,合法下标范围是0 ≤ pos < size(),这个操作不会触发字符串扩容,也不会修改字符串维护的size()长度计数。
  • 初始为空的stringsize()为0,直接写r[i] = 'a'属于未定义行为:多数实现下不会立刻触发崩溃,但写入的位置不属于字符串的有效字符存储区,既没有把字符存到正确位置,也不会更新长度计数,循环跑完size()自然还是0。

和push_back的行为差异

push_back是专门的尾部追加接口,每次调用时会自动检查当前剩余存储容量,容量不足就触发扩容,写入新字符后会主动将size()加1,所以循环追加5次后长度为5,符合预期。

问题复现代码

#include <iostream>
#include <string>
using namespace std;

int main() {
    string r;
    int i;
    for(i = 0; i < 5; ++i)
    {
        r[i] = 'a'; // 未定义行为,不会修改有效内容和长度
    }
    cout << r.size();    // 输出0
    cout << endl;

    for(i = 0; i < 5; ++i)
    {
        r.push_back('a'); // 正常追加,自动扩容更新长度
    }
    cout << r.size();    // 输出5
    return 0;
}

如果要使用[]赋值的正确前置操作

如果确实需要用下标运算符批量填充内容,必须先手动给字符串设置足够的有效长度,再通过下标写入:

string r;
r.resize(5); // 提前分配5个字符的有效存储空间,此时size()已经为5
for(int i = 0; i < 5; ++i)
{
    r[i] = 'a'; // 合法访问,写入有效位置
}
// 最终r内容为"aaaaa",size()返回5

注意不要混淆resize()和reserve():reserve()仅预分配底层存储容量,不会修改size()值,调用后直接用下标访问依然属于未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:54:28