以下代码编译但在未使用GCC优化时会出现分段错误:
#include <stdio.h>
#define n 10000000
int main()
{
fprintf(stderr, "Array with size %ld\n", n * sizeof(double));
double a[n];
return 0;
}
$ gcc -O0 a.c && ./a.out
Segmentation fault (core dumped)
$ gcc -O1 a.c && ./a.out
Array with size 80000000
我测试了-O1,-O2,-O3,甚至用-Og也可以。但是-O0就是段错误。我正在使用GCC 5.3.0。
如果我删除了fprintf,或者我将数组更改为静态double [N],则没有分段错误。
为什么呢?发生了什么事?
答案 0 :(得分:7)
默认的堆栈大小通常很小(例如8MB)。您的数组大小可能太大并且溢出堆栈。 您可以尝试使用以下命令更改* nix系统上的默认堆栈大小:
ulimit -s unlimited
在一般情况下,没有可移植的解决方案来确定具有自动存储持续时间(也称为“堆栈”)的给定阵列分配是否会成功。所以当你分配一个相当大的对象时,最好使用malloc()
。
答案 1 :(得分:5)
你刚刚耗尽了堆栈空间。
double a[n];
在堆栈上分配,大小约为40(80?)兆字节。
使它成为static
意味着它不再在堆栈上 - 并且启用优化将意味着编译器实际上从未实际分配它。