如何在C语言中声明和使用10亿个整数的巨大数组?

如何在C语言中声明和使用10亿个整数的巨大数组?,c,memory-management,C,Memory Management,我正在实现一个顺序排序程序,就像快速排序一样。我想在一个由1或100亿个整数组成的庞大数组中测试我的程序的性能。 但问题是,由于数组的大小,我得到了一个分割错误 此数组声明的示例代码: #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 1000000000 int main(int argc, char **argv) { int list[N], i; srand(

我正在实现一个顺序排序程序,就像快速排序一样。我想在一个由1或100亿个整数组成的庞大数组中测试我的程序的性能。 但问题是,由于数组的大小,我得到了一个分割错误

此数组声明的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 1000000000

int main(int argc, char **argv)
{
  int list[N], i;
  srand(time(NULL));
  for(i=0; i<N; i++)
     list[i] = rand()%1000;
  return 0;
}
#包括
#包括
#包括
#定义N 100000000
int main(int argc,字符**argv)
{
int list[N],i;
srand(时间(空));

对于(i=0;i您必须使用
malloc
来进行这种分配。堆栈上的大部分几乎每次都会失败

int *list;

list = malloc(N * sizeof(int));

这会将分配放在有更多可用内存的堆上。

您可能不会创建这么大的数组,如果创建了,您肯定不会在堆栈上创建它;堆栈没有那么大

如果您有一个32位地址空间和一个4字节的
int
,那么您就无法创建一个具有10亿
int
s的数组;内存中将没有足够的连续空间来容纳这么大的对象(可能没有足够的连续空间容纳一个只有该大小一小部分的对象)。如果您有一个64位地址空间,您可能不会分配那么多空间


如果您真的想尝试,您需要静态地创建它(即,在文件范围内声明数组,或在函数中使用
static
限定符)或动态地创建它(使用
malloc
)。

Michael是对的,您不能在堆栈中容纳那么多。但是,您可以将其设置为全局(或静态)如果你不想破坏它

#include <stdlib.h>
#include <time.h>
#define N 1000000000
static int list[N];

int main(int argc, char **argv)
{
  size_t i;
  srand(time(NULL));
  for(i=0; i<N; i++)
     list[i] = rand()%1000;
  return 0;
}
#包括
#包括
#定义N 100000000
静态整数列表[N];
int main(int argc,字符**argv)
{
尺寸i;
srand(时间(空));

对于(i=0;i而言,另一个选项是动态分配一个较小数组的链接列表。您必须使用访问器函数对其进行包装,但与单个4 GB内存块相比,您更可能获取16 256 MB内存块

typedef struct node_s node, *node_ptr;
struct node_s
{
    int data[N/NUM_NODES];
    node_ptr next;
};

在linux系统上,非常大的块的
malloc
只是在引擎盖下执行
mmap
,因此研究它可能太单调了

请注意,数组边界和索引既没有溢出(有符号整数),也没有无符号换行(无符号整数)。请使用
size\t
作为类型,因为您在64位计算机上,这样应该可以工作


但是作为一种习惯,你应该根据
SIZE\u MAX
检查你的边界,比如
assert(N*sizeof(data[0])堆栈分配会使它中断。N=1Gig ints=>4Gig内存(使用32位和64位编译器)。但是
如果您想衡量quicksort或您的类似算法的性能,这不是一种方法。
试着在准备好的大样本上按顺序使用多个快速排序

-create a large random sample not more than half your available memory.
make sure it doesn''t fill your ram!
If it does all measuring efforts are in vain. 
500 M elements is more than enough on a 4 gig system.

-decide on a test size ( e.g. N = 100 000 elements)
-start timer 
--- do the algoritm for ( *start @ i*N, *end @ (i+1)*N) 
(rinse repeat for next i until the large random sample is depleted)
-end timer

现在,对于算法消耗的时间,您有了一个非常精确的答案。请运行几次,以了解“有多精确”(每次使用一个新的srand(seed)seed)。并更改N以进行更多检查。

您的计算机有多少物理内存?@BlueCode:这可能不重要;重要的是虚拟内存;并非进程地址空间中所有分配的内存都需要立即由RAM备份。请尝试将其放在堆而不是堆栈上。最大堆栈大小很可能是受操作系统或c运行时的限制您必须小心,
malloc(N*sizeof(int))
也可能会失败,一些编译器会对可分配的最大连续卡盘进行限制。和N*sizeof(int)可能会在32位计算机上溢出。@AlexandreC。不,不会。32位计算机上的
大小\u t
必须几乎是32位,无符号,因此适合。这并不是说你可以分配那么多内存though@AnttiHaapala:如果N为20亿,则N*sizeof(int)将溢出。@AlexandreC.
N==1000000000
N!=1073741824
N!=2000000000
操作海报说明这是一台64位的机器,因此应该适合虚拟地址空间。感谢您的建议,我认为,在这种数据结构中应用像快速排序这样的简单排序算法将很困难。谢谢谢谢你的回复。我已经测试了使用malloc动态分配和使用全局变量。这两种解决方案都很有效,但是使用全局参数会导致编译,这需要很长时间(大约8分钟)。@dlpcoder:尝试阅读以下内容:
assert(N*sizeof(data[0])