2012-07-28 76 views
2

我正在处理一个C程序。我想初始化一个长度为1,000,000的数组。
它编译时没有任何错误或警告,但在执行过程中,Windows发送进程终止。
我修改了我的代码,所以会有4个数组,每个数组有500,000个整数。它再次编译没有错误或警告,但问题仍然存在。C中的数组长度是否有限制?

我用CodeBlox(GCC编译器,我认为)

这里是我的代码:

#include <stdio.h> 
#include <math.h> 
// Prototypes: 
int checkprime(int n); 

int main(){ 
int m=0; 

    int A[500001]={2,2,0};//from k=1 to 500000 
    int B[500000]={0};//from k=500001 to 1000000 
    int C[500000]={0};//from k=1000001 to 1500000 
    int D[500000]={0};//from k=1500001 to 2000000 
    int n=3; 
    int k=2; 
     for(n=3;n<2000001;n +=2){ 
      if(checkprime(n)){ 

       if (k<=500000) 
       {A[k]=n; 
       k +=1;} 

       else if ((k>500000)&&(k<=1000000)) 
       {B[k-500001]=n; 
       k +=1;} 
       else if ((k>1000000)&&(k<=1500000)){ 
       C[k-1000001]=n; 
        k +=1; 
       } 
       else if(k>1500000){ 
       D[k-1500001]=n; 
       k +=1;} 
       }//end of if 

      }//end for 

    int i=0; 
    for(i=1;i<500001;i++) 
    { 
     m=m+A[i]; 
    } 
    for(i=0;i<5000001;i++) 
    { 
     m=m+B[i]; 
    } 
    for(i=0;i<5000001;i++) 
    { 
     m=m+C[i]; 
    } 
    for(i=0;i<5000001;i++) 
    { 
     m=m+D[i]; 
    } 
    printf("answer is %d",m); 
return 0;//Successful end indicator 
}//end of main 

int checkprime(int n){ 
int m=sqrt(n); 
if (!(m%2)) 
{ 
    m=m+1; 
} 
int stop=0; 
int d=0; 
int isprime=1; 
while((m!=1)&&(stop==0)){ 
d=n%m; 
if (d==0){ 
    stop=1; 
    isprime=0; 
    } 
m -=2; 

}//end of while 
return isprime; 
}//end of checkprime 
+1

重新:阵列长度限制,请参见:http://stackoverflow.com/questions/216259/is-有一个最大数组长度限制在c – pb2q 2012-07-28 06:21:36

+0

向我们显示您的代码。 – 2012-07-28 06:23:23

+0

@KeithRandall不需要。 – 2012-07-28 06:24:14

回答

0

是的,有。

本地数组在堆栈上创建,如果数组太大,堆栈将与内存中的其他内容冲突并导致程序崩溃。

+0

不!声明为'static'的数组*不*堆栈分配! – 2012-07-28 06:24:45

+0

@BasileStarynkevitch我不是说声明为'静态'的数组。我的意思是静态分配数组。 – 2012-07-28 06:27:45

+0

这些不称为静态分配,而是本地数组。 – 2012-07-28 06:29:34

1

我希望你的巨大的初始化数组是静态的或全局的。如果它是一个局部变量,它会在运行时溢出堆栈。

我相信GCC的旧版本在初始化数组时有次优行为(可能是二次方时间)。我也相信标准可能会定义一个所有符合编译器应该接受的(小)最小数组大小(对于字符串大小有一个这样的下限,它可能小到512)。

IIRC,GCC的最新版本在初始化静态数组时改进了它们的行为。与GCC 4.7

随着试试我的Debian/Sid的gcc-4.7.1我能够编译biga.c文件开始

int big[] = {2 , 
3 , 
5 , 
7 , 
11 , 
13 , 

399999937 , 
399999947 , 
399999949 , 
399999959 , 
}; 

结束和含23105402线:

% time gcc -c biga.c 
gcc -c biga.c 43.51s user 1.87s system 96% cpu 46.962 total 

% /usr/bin/time -v gcc -O2 -c biga.c 
Command being timed: "gcc -O2 -c biga.c" 
User time (seconds): 48.99 
System time (seconds): 2.10 
Percent of CPU this job got: 97% 
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:52.59 
Average shared text size (kbytes): 0 
Average unshared data size (kbytes): 0 
Average stack size (kbytes): 0 
Average total size (kbytes): 0 
Maximum resident set size (kbytes): 5157040 
Average resident set size (kbytes): 0 
Major (requiring I/O) page faults: 0 
Minor (reclaiming a frame) page faults: 691666 
Voluntary context switches: 25 
Involuntary context switches: 5162 
Swaps: 0 
File system inputs: 32 
File system outputs: 931512 
Socket messages sent: 0 
Socket messages received: 0 
Signals delivered: 0 
Page size (bytes): 4096 
Exit status: 0 

这是在具有16Gb RAM的i7 3770K桌面上。

巨大数组作为当地人,甚至里面main总是一个坏主意。可以堆分配它们(例如,使用callocmalloc,然后free),也可以将它们设为全局或静态。调用堆栈上的本地数据空间始终是一个恐慌资源。典型的调用帧(所有局部变量的组合大小)应小于一千字节。大于兆字节的呼叫帧几乎总是不好且不专业。

+0

你知道任何有效处理这些东西的现代C环境吗?(MS Visual或Dev除外)在基于Linux的操作系统上编程是否也存在此运行时问题? – 2012-07-28 09:43:53

+0

问题出在您的代码中。即使Linux有堆栈大小限制(但你可以配置它们)。 – 2012-07-28 09:47:24

1

使用ulimit命令控制最大堆栈大小的限制。编译器可以(或不)设置更小的限制,但不能大于此限制。
要查看电流限制(以千字节):

ulimit -s 

要删除限制:

ulimit -s unlimited 
+0

我应该在哪里输入这些代码?在Ubuntu终端上? – 2012-07-28 09:40:36

+0

就你而言,最好学会使用'calloc'和'free'。一般来说,堆栈大小总是有限制的。 – 2012-07-28 09:55:19

+0

@PooyaMoradi: - 是的,在终端。 – 2012-07-28 09:57:15