Windows下使用Cygwin/MinGW调整C++程序栈大小的方法问询
解决递归程序栈溢出的正确栈大小调整方法及问题分析
首先,先解决你那个编译命令报错的问题——你写的g++ -std=c++11 -Wl --stack <stack size> file.c -o file格式不对,导致链接器把--stack当成了输入文件,才会报“不是有效的文件”。
正确的Windows平台(MinGW编译器)编译命令
-Wl选项是告诉gcc把后续参数传递给链接器,但参数之间必须用逗号分隔,不能用空格。正确的命令应该是:
g++ -std=c++11 -Wl,--stack,10485760 file.cpp -o file
这里10485760是10MB的字节数,你可以根据递归深度需求调整(比如20MB就是20971520)。注意--stack是MinGW链接器针对Windows系统的选项,用来设置程序的初始栈大小。
Linux平台的栈大小调整方式
Linux下没法通过编译时的链接器选项直接设置栈大小,因为栈大小是由系统的ulimit机制控制的:
- 临时调整:在运行程序前,先执行
ulimit -s 20480(这里20480是20MB,单位是KB),然后再运行你的程序; - 永久调整:编辑
/etc/security/limits.conf文件,添加以下内容(替换成你的用户名):
保存后重启或重新登录系统,设置就会生效。username soft stack 20480 username hard stack 20480
第一种方法未生效的可能原因
- 平台不匹配:如果第一种方法是用了类似
#pragma comment(linker,"/STACK:10485760")的代码内设置,这个是MSVC编译器的语法,如果你用的是MinGW,可能会被忽略;反过来如果用MSVC却用了--stack链接选项也会无效。 - 栈大小设置不足:10万个元素的快速排序,最坏情况递归深度是O(n)(比如数组已经有序时),每层递归的栈帧至少包含几个变量和返回地址,算下来可能需要十几MB甚至更大的栈空间,如果你设置的数值太小,还是会溢出。
- 编译器优化问题:有些编译器默认不会开启尾递归优化,而快排的递归并非尾递归,所以没法自动把递归转为迭代,栈占用还是会很高。
额外建议:从代码层面避免栈溢出
调整栈大小是治标不治本的方法,极端情况下(比如递归深度真的达到10万层),再大的栈也可能不够。更可靠的方式是:
- 把递归版快速排序改成迭代版,用手动模拟栈(比如用
std::stack)来存储需要处理的区间; - 设置递归深度阈值,当递归深度超过某个值(比如1000)时,切换到非递归的排序方法(比如插入排序)。
内容的提问来源于stack exchange,提问作者Shantanu Shinde
相关产品推荐
相关产品推荐

