C++创建大容量set<vector<bool>>数组触发段错误的原因排查
搞定栈溢出导致的SIGSEGV段错误
嘿,我来帮你分析下这个问题——你遇到的退出码-1073741571和SIGSEGV段错误,本质上就是栈空间不够用了,和Eclipse本身没啥关系,是不同环境的栈限制差异导致的。
为啥会出问题?
默认情况下,Windows系统里每个线程的栈大小通常只有1MB左右,而你直接在栈上声明了一个包含43309个std::set<std::vector<bool>>的数组:
set<vector<bool>> C[43309];
别小看单个std::set对象,它内部要存红黑树的指针,在MSVC里大概占24字节。算一下:43309 × 24 ≈ 1.04MB,再加上内存对齐的额外开销,刚好超过了Windows默认栈的容量,直接把栈撑爆了,就触发了段错误。
那为啥ideone上能正常跑?因为在线编译器一般用Linux环境,默认栈大小是8MB左右,完全装得下这个数组,所以没出问题。
怎么解决?
方案1:把数组移到堆上(强烈推荐)
栈本来就不是用来存大数组的,大内存该放堆里。用std::vector来管理最省心,它会自动在堆上分配内存,还不用手动释放:
#include <iostream> #include <cmath> #include <omp.h> #include <set> #include <vector> using namespace std; int main() { vector<set<vector<bool>>> C(43309); // 堆上分配,再也不怕栈不够 }
要是你习惯用动态数组,也可以这么写:
set<vector<bool>>* C = new set<vector<bool>>[43309]; // 记得用完后释放内存,不然会内存泄漏 delete[] C;
但还是std::vector更安全,不用操心内存释放的事儿。
方案2:调大栈大小(不推荐,移植性差)
如果你非得在栈上放这个数组,也可以改编译器的栈大小设置:
- 用MSVC的话,在Eclipse的链接器选项里加
/STACK:2097152,2097152,把栈设成2MB。 - 用MinGW的话,加编译选项
-Wl,--stack,2097152。
不过这个方法不推荐,换个环境(比如别人的电脑)可能又会出问题,移植性太差。
额外提一句
别怀疑std::vector<bool>,它虽然是个特殊的bit压缩容器,但这次的锅真不是它的——哪怕你换成std::vector<int>,只要数组够大,照样会栈溢出。
内容的提问来源于stack exchange,提问作者nanda
相关产品推荐
相关产品推荐

