
pop_back() 只能删最后一个元素,且容器必须非空
pop_back() 是 std::vector、std::string 等序列容器的成员函数,作用就是移除末尾那个元素。它不接受参数,也不返回被删的值,只改变容器大小。
常见错误是没检查空容器就调用:vec.pop_back() 在 vec.empty() 为 true 时会触发未定义行为(不是抛异常,而是直接崩或静默错乱)。
使用场景很明确:你确定有东西可删,且只要删最后一个。比如解析日志时逐个弹出临时缓存项。
- 不能用于
std::list或std::deque的“末尾”以外位置 - 时间复杂度是 O(1),但对
std::vector可能触发内存重分配(实际不会,因为只是减 size) -
pop_back()不释放内存,capacity()不变
erase() 可删任意位置,但要注意迭代器失效
erase() 是更通用的删除接口,支持删单个元素、一段区间,甚至整个容器。删末尾时写法是:vec.erase(vec.end() - 1) 或 vec.erase(--vec.end())。
立即学习“C++免费学习笔记(深入)”;
关键区别在于:它返回一个有效迭代器(指向被删元素后一个),且对空容器调用 erase() 是安全的——只要你传的迭代器合法。但 vec.end() - 1 在空时就是非法操作,照样崩溃。
性能上,用 erase() 删末尾和 pop_back() 几乎一样快;但删中间或开头,vector::erase() 是 O(n),因为要搬动后面所有元素。
- 删末尾推荐用
pop_back(),语义清晰、不易写错 - 删多个连续末尾元素?
erase(vec.end() - n, vec.end())比连调n次pop_back()略快(少改 size 多次) -
string::erase()行为一致,但注意std::string的 C++11 后是“短字符串优化”,小字符串删完可能不释放堆内存
删末尾元素前,先确认容器类型和是否为空
不是所有容器都有 pop_back()。比如 std::map、std::set 就没有——它们根本没“末尾”概念。而 std::deque 两者都有,std::list 也有,但 erase(--c.end()) 和 pop_back() 效果相同。
最容易被忽略的是空检查逻辑位置。有人写:
if (!vec.empty()) vec.pop_back();
这没问题;但若写成:
auto it = vec.end(); --it; vec.erase(it);
就漏了判空,vec.end() 对空容器是合法的,但 --it 是未定义行为。
- 统一用
empty()判空,别依赖size() > 0(虽然等价,但empty()更直白且某些容器size()是 O(n)) - 用
erase()时,优先用iterator形式而非index形式,避免隐式转换和越界风险 -
std::string的pop_back()是 C++11 引入的,老项目若需兼容 C++98,只能用erase()
删完别假设容量收缩,需要时手动 shrink_to_fit
无论 pop_back() 还是 erase(),标准库都不保证释放多余内存。vector 的 capacity() 通常不变,除非你显式调 shrink_to_fit()。
这在长期运行、反复增删的程序里可能造成内存浪费。但 shrink_to_fit() 是“建议”而非强制,实现可以忽略;而且它本身是 O(n),会重新分配+拷贝。
- 高频小量删末尾(如网络包解析),完全不用管
capacity - 一次性删掉大半内容后,再追加新数据前,考虑
shrink_to_fit() -
string::shrink_to_fit()同样适用,但部分 libstdc++ 实现里对短字符串无效
事情说清了就结束










