当尝试声明一个大数组时出现分段错误和核心转储

5
在我的C程序中,当我尝试分配这个数组的值时:
double sample[200000][2];

我遇到了段错误。但是当我使用以下命令时:

double sample[20000][2]

它可以工作!!这些索引值有限制吗?

2个回答

9

看起来你试图为200,000 x 2 = 400,000个双精度值预留空间,每个double占用8个字节,因此你试图预留约3.2兆字节

尽管你的计算机可能有几个G的内存,但每个进程和线程的堆栈空间都是有限制的,可能被限制在1或2兆字节。所以你不能分配3兆字节,否则会崩溃。

要解决这个问题,你需要改用动态内存,使用malloc函数。
这将让你从堆空间中分配内存,而堆空间比栈空间更加充足。

使用malloc的方法如下:

double (*sample) [200000];
s = malloc(sizeof(*sample) * 2); 
sample[0][0] = 0.0;
sample[1][199999] = 9.9;

@ZanLynx:您说得部分正确,我忘记了一层级别的间接性(*)。现在已经修复。 - abelenky
我必须同意@ZanLynx,我不明白你的分配代码是如何工作的。 - Shafik Yaghmour
我用一个我试过的代码示例修改了你的代码示例。 - Zan Lynx
@ZanLynx,这还是错误的,因此 200000double类型将在自动存储中,而较小的第二维将是动态的,这绝对不是最初的意图。 - Shafik Yaghmour
@ShafikYaghmour:自动存储?不是的。在上面的代码中,sample是一个指向包含200,000个双精度浮点数的数组的指针。malloc(sizeof(*sample)*2)请求动态分配这两个数组,总共有400,000个双精度浮点数。 - Zan Lynx

6
你很可能正在溢出堆栈,因为在大多数现代实现中,它们是自动变量,将分配在具有有限大小的堆栈上。
例如,在visual studio中,默认情况下堆栈大小为1MB,但可修改。这里有一个更完整的典型堆栈大小列表here
SunOS/Solaris   8172K bytes
Linux           8172K bytes
Windows         1024K bytes
cygwin          2048K bytes

如果你有大量数据需要分配,一种替代堆栈的方法是使用malloc进行动态分配C FAQ提供了一个关于如何动态分配多维数组?的好参考,可以修改它们的双重示例以适用于 double
#include <stdlib.h>

double **array1 = malloc(nrows * sizeof(double *));
for(i = 0; i < nrows; i++)
   array1[i] = malloc(ncolumns * sizeof(double));

1
只是一些关于栈的注释:一些系统具有“无限”堆栈大小,因为它会根据需求增长。但是当线程被添加时,堆栈突然具有固定大小,因为每个堆栈需要一个唯一的位置,并且很快就会遇到相邻的内存分配问题。 - Zan Lynx
我该如何修改堆栈大小?我在这里使用gcc编译器。 - james
@james 你用的是什么操作系统? - Shafik Yaghmour
@James:「我该如何修改堆栈大小?」这是错误的问题。正确的问题应该是「我该如何避免在堆栈上分配内存?」 - abelenky
1
@DanielKamilKozar:我认为标准没有定义最小尺寸。例如,在16位计算机上,您将受到64KB对象的限制。然而,这曾经是一种常见的C编程环境。 - Zan Lynx
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接