在 C++ 中,以下哪个函数调用会造成栈溢出?( )
这题考函数调用栈和递归,拿到题先看每个函数有没有终止条件。C 项函数里既自己调用自己又分配了大数组,无限递归 + 大栈帧,必爆栈。
很多同学习惯只盯着递归深度,觉得只要写了终止条件就没事,忽略了无限递归一定会栈溢出。C 项最典型的坑就是同时有大数组,让栈帧变得很大,加速了栈耗尽的过程。
这题考查函数调用栈(stack)和递归。栈溢出就是栈空间不够用了。每次函数调用都会在栈上压入一个栈帧,里面装着局部变量、参数和返回地址。若递归没有终止条件,栈帧会一直压下去;若栈帧本身很大,也会加速耗尽栈空间。
命题人喜欢挖两个坑:一是让你以为“有递归就有终止条件”,其实 C 项根本没有基线条件,是死循环;二是利用局部大数组把栈帧做大,让溢出更快发生,迷惑那些只关注递归层数的同学。
逐个看选项:
int foo() { return 0; }:普通函数,调用一次就返回,栈帧很小,不会溢出。int bar() { int x = 1; return x; }:也是普通函数,栈帧里只有一个 int,安全。void baz() { int a[1000]; baz(); }:危险。函数内部先分配 a[1000](约 4KB),然后立即调用自己,没有任何终止条件。每次调用都在栈上再压一个 4KB 的栈帧,无限递归下去,栈很快就会被撑爆。void qux() { return; }:空函数,调用即返回,安全。因此只有 C 会造成栈溢出。
无限递归一定会栈溢出,只是时间问题。实际竞赛中还要注意递归深度:即使有终止条件,如果深度达到几十万层也会溢出(因为栈空间通常只有几 MB)。C 项同时有大数组,让栈帧变大,加速了溢出。
函数与递归在题库共考过 67 题,覆盖 8 个级别,逐年分布:2008 年 2 题、2013 年 1 题、2021 年 1 题、2023 年 13 题、2024 年 18 题、2025 年 21 题、2026 年 6 题、null 年 5 题。递归函数共考过 115 题,覆盖 8 个级别,逐年分布:2007 年 4 题、2008 年 4 题、2009 年 2 题、2010 年 2 题、2012 年 2 题、2013 年 3 题、2014 年 1 题、2019 年 2 题、2020 年 1 题、2021 年 5 题、2022 年 2 题、2023 年 7 题、2024 年 25 题、2025 年 15 题、2026 年 18 题、null 年 22 题。栈(stack)共考过 89 题,覆盖 8 个级别,逐年分布:2007 年 1 题、2008 年 4 题、2009 年 3 题、2010 年 3 题、2012 年 3 题、2014 年 1 题、2015 年 1 题、2016 年 2 题、2017 年 1 题、2018 年 1 题、2020 年 3 题、2021 年 5 题、2022 年 5 题、2023 年 4 题、2024 年 25 题、2025 年 15 题、2026 年 9 题、null 年 3 题。
从数据看,2024 年函数与递归、递归函数、栈三个考点都达到了近年峰值(18 题、25 题、25 题),2025 年继续保持高位(21 题、15 题、15 题),2026 年略有回落但仍不少(6 题、18 题、9 题)。这说明无限递归与栈溢出的概念仍是高频考点。未来命题可能继续用“无终止条件的递归 + 大栈帧”的组合来挖坑,也可能在更复杂的递归场景中考察栈帧大小对溢出速度的影响。暂无足够依据预测具体年份或题量。