size() 返回当前元素个数,capacity() 返回已分配内存可容纳的元素总数;resize(n) 改变 size() 并可能初始化新元素,reserve(n) 仅预分配 capacity() 不改变 size()。
很多人调用 size() 看到 10 就以为内存占了 10 个元素的空间,其实不一定。size() 返回当前实际存了多少个元素,capacity() 才是底层分配的连续内存能容纳多少个——它往往 ≥ size(),因为 vec
tor 会预留空间避免频繁 realloc。
reserve(n) 预分配容量,可避免多次拷贝重分配(尤其对非 trivial 类型)resize(n) 会改变 size():若 n > size(),末尾补默认构造对象;若 n ,直接截断(已析构)
shrink_to_fit() 是非强制请求,编译器可能忽略;想真正释放多余内存,得靠 swap 技巧:std::vector(v).swap(v);
operator[] 不做边界检查,越界是未定义行为(常见 crash 或静默脏读);at(index) 会检查,越界时抛 std::out_of_range 异常。
at(),上线后若确定索引安全、且性能敏感,再换 []
push_back() 触发扩容),所有已有迭代器、指针、data() 返回的地址都失效,但 at() 和 [] 只依赖 index,不受影响front() 或 back() 同样是未定义行为,必须先判空erase(iterator) 返回下一个有效迭代器,不是 void;如果写成 v.erase(it++); 就跳过下一个元素——因为 it++ 先返回旧值再自增,而 erase 已让旧 it 失效。
it = v.erase(it); // 安全,it 指向原 it+1
v.erase(std::remove_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; }), v.end());for (int i = 0; i 边删边改 size,会导致漏删或越界;改用反向遍历或 while + erase 返回值
std::vector 是 C++ 标准强制要求的位压缩特化,它不存储 bool 对象,而是把 8 个 bool 打包进 1 字节。这导致几个关键差异:
operator[] 返回的是代理对象 std::vector::reference ,不是 bool&,所以不能取地址:bool* p = &v[0]; // 编译失败
std::vector::iterator 是自定义类,某些算法(如需要指针算术的)可能不兼容std::deque 或 std::vector(用 0/1 代替 false/true)vector 的“常用”背后藏着不少隐式契约:capacity 变化时机、迭代器失效规则、特化陷阱……这些不显眼的地方,才是线上 bug 最爱藏身的位置。