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

重复执行pop_back()与push_back()引发Segmentation fault原因求解

问题根因分析

你的代码触发了C++标准定义的未定义行为(UB):std::vector的pop_back()成员函数有前置要求——调用时容器必须非空,空容器执行pop_back()的行为没有任何标准约束,段错误是这类未定义行为的典型表现之一。

我们可以明确原代码的执行逻辑:

  1. 初始状态下test是空容器
  2. 第一次循环i=0,满足i % 2 == 0,执行push_back(0),容器大小变为1
  3. 紧接着执行pop_back(),容器回到空状态
  4. 第二次循环i=1,不满足if条件,不会执行push_back,容器保持空
  5. 直接执行pop_back(),此时为空容器调用pop_back,触发未定义行为,表现为段错误。

各修改操作消除错误的原理
  • 删除if语句:每次循环都会先执行push_back让容器大小+1,再执行pop_back让大小-1,容器永远不会为空,不会触发空pop的未定义行为,自然不会出现段错误。
  • 在pop_back前添加else关键字:此时逻辑变为if(i%2==0) push_back(i); else pop_back();,执行流为:i=0push(大小1)→i=1pop(大小0)→i=2push(大小1)→i=3pop(大小0),永远是push和pop交替执行,不会出现空容器时调用pop_back的情况,不会触发未定义行为。
  • 单独移除push_back操作:未定义行为不代表必然崩溃,其表现完全由编译器实现、编译参数、运行环境决定。当你移除push_back后,第一次循环就会触发空pop的未定义行为,但部分编译器的std::vector实现中,空pop_back不会直接访问非法内存,只是对内部size计数做减法,不会触发段错误;如果你在循环前预先push了若干元素,只要pop的总次数不超过预先push的元素数量,容器就不会变空,自然也不会出现问题。
  • 单独移除pop_back操作:全程只有push_back操作,容器持续扩容,永远不会出现空容器调用pop_back的场景,不会触发错误。

补充说明:你观察到“移除push_back后哪怕预先push若干元素也不会出问题”,本质是如果预先push的元素数量≥循环次数,容器全程不会为空,自然不会触发未定义行为;如果预先push的数量小于10000,依然会触发空pop的未定义行为,只是不一定表现为段错误而已,这正是未定义行为的典型特征:没有固定的错误表现,可能崩溃、可能正常运行、也可能输出异常结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 12:06:05