C++中向string插入字符时[]下标运算符与push_back方法的区别
C++空string用[]下标赋值失效的根本原因
核心是对std::string的下标运算符行为存在认知偏差:
operator[]的设计逻辑是仅访问字符串有效长度范围内的已存在元素,合法下标范围是0 ≤ pos < size(),这个操作不会触发字符串扩容,也不会修改字符串维护的size()长度计数。- 初始为空的string
size()为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
相关产品推荐
相关产品推荐

