vector初始化用v(10)会构造10个默认对象而非仅分配空间;reserve()只增容不改变size,访问元素仍需确保索引有效;频繁push_back未reserve会导致多次扩容拷贝;insert/erase后迭代器易失效,应使用返回值更新迭代器;emplace_back仅在能直接构造时优于push_back;clear不释放内存,shrink_to_fit为非强制收缩请求,swap技巧虽可靠但有额外开销。

vector 初始化和内存分配容易踩的坑
直接用 vector<int> v(10)</int> 会构造 10 个默认初始化的 int(即全 0),不是预留空间;想只分配容量不构造元素,得用 reserve()。但注意:reserve() 不改变 size(),调用 v[0] 仍越界。
-
vector<int> v(10)</int>→v.size() == 10,已构造 10 个对象 -
vector<int> v; v.reserve(10)</int>→v.size() == 0,v.capacity() >= 10 - 频繁 push_back 又没 reserve,可能触发多次 realloc + 元素拷贝(对非 trivial 类型代价高)
insert / erase 后迭代器失效怎么判断
insert() 和 erase() 都可能导致部分或全部迭代器、指针、引用失效——这是 vector 的底层连续内存特性决定的,不是 bug。
- 所有指向被 erase 元素及之后位置的迭代器全部失效
-
insert()若引起扩容,所有迭代器全失效;否则仅插入点及之后的迭代器失效 - 安全写法:用
erase()返回的新迭代器继续遍历,比如it = v.erase(it),别写v.erase(it++);
用 emplace_back 替代 push_back 的实际效果
emplace_back() 是就地构造,绕过临时对象和拷贝/移动;但只有传参能直接构造元素类型时才真正省开销。
- 对
vector<string></string>,v.emplace_back("hello")比v.push_back(string("hello"))少一次 string 构造 - 对
vector<int></int>,emplace_back(42)和push_back(42)汇编几乎一样,无实质差别 - 传入已存在的对象(如
v.emplace_back(x)),仍会调用移动构造,不一定比push_back(x)快
clear() 不释放内存,swap 技巧要慎用
clear() 只销毁元素、设 size() 为 0,但 capacity() 不变——内存没还给系统。想真正收缩,传统做法是 vector<t>().swap(v)</t>,但 C++11 起更推荐 v.shrink_to_fit()。
立即学习“C++免费学习笔记(深入)”;
-
shrink_to_fit()是非强制请求,编译器可忽略(比如 libc++ 实现常不缩容) -
swap()方式 100% 释放,但多一次 move 构造开销,且对有自定义 allocator 的 vector 可能出问题 - 如果后续确定还要往里塞大量数据,留着 capacity 反而是好事,别盲目 shrink
vector 的“自动管理”只管 size 和构造/析构,容量策略、迭代器生命周期、移动语义边界这些,都得自己盯紧。稍不注意,性能毛刺或崩溃就藏在看似最顺手的操作里。










