我正在研究C中的程序。我想初始化一个长度为1,000,000的数组 它编译时没有任何错误或警告,但在执行过程中,窗口发送进程终止 我修改了我的代码,因此将有4个数组,每个数组有500,000个整数。它再次编译没有错误或警告,但问题仍然存在。
我使用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
答案 0 :(得分:1)
我希望您的巨大初始化数组是静态的或全局的。如果它是局部变量,它将在运行时溢出堆栈。
我认为旧版本的GCC在初始化数组时具有次优行为(可能是二次时间)。
我还认为 C 标准可能会定义一个(小)最小数组大小,所有符合条件的编译器都应该接受(字符串大小有这么低的限制,它可能小到512) )。
IIRC,最新版本的GCC在初始化静态数组时改进了它们的行为。试试GCC 4.7使用我的Debian / Sid gcc-4.7.1
我可以编译一个{/ 1}}文件,以
biga.c
以
结尾int big[] = {2 ,
3 ,
5 ,
7 ,
11 ,
13 ,
并包含23105402行:
399999937 ,
399999947 ,
399999949 ,
399999959 ,
};
这是在带有16Gb RAM的i7 3770K台式机上。
将大型数组作为本地人,即使在 % 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
内总是一个坏主意。要么堆分配它们(例如,使用main
或calloc
,然后适当地malloc
,或者将它们设置为全局或静态。调用堆栈上的本地数据空间始终是一种恐慌资源。典型的调用框架(所有局部变量的组合大小)应小于1千字节。大于兆字节的呼叫帧几乎总是坏的和不专业的。
答案 1 :(得分:1)
使用ulimit命令控制的最大堆栈大小限制。编译器可以(或不)将限制设置得更小,但不能大于此 要查看当前限制(以千字节为单位):
ulimit -s
删除限制:
ulimit -s unlimited
答案 2 :(得分:0)
是的,有。
在堆栈上创建本地数组,如果您的数组太大,堆栈将与内存中的其他内容冲突并使程序崩溃。