Reputation: 973
I'm working on a program in C. I want to initialize an array which has a length of 1,000,000
It compiles without any errors or warnings but in the execution, windows sends a process termination.
I modified my code so there will be 4 arrays each having 500,000 integers. It again compiles without error or warning but the problem still exists.
I use CodeBlox (GCC compiler, I think)
Here is my code:
#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
Upvotes: 2
Views: 5769
Reputation: 1
I hope your huge initialized array is static or global. If it is a local variable it would overflow the stack at runtime.
I believe that old versions of GCC had sub-optimal behavior (perhaps quadratic time) when initializing an array.
I also believe that the C standard might define a (small) minimal array size which all conforming compilers should accept (there is such a lower limit for string sizes, it might be as small as 512).
IIRC, recent versions of GCC improved their behavior when initializing static arrays. Try with GCC 4.7
With my Debian/Sid's gcc-4.7.1
I am able to compile a biga.c
file starting with
int big[] = {2 ,
3 ,
5 ,
7 ,
11 ,
13 ,
and ending with
399999937 ,
399999947 ,
399999949 ,
399999959 ,
};
and containing 23105402 lines:
% 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
This is on a i7 3770K desktop with 16Gb RAM.
Having huge arrays as locals, even inside main
is always a bad idea. Either heap-allocate them (e.g. with calloc
or malloc
, then free
them appropriately) or make them global or static. Space for local data on call stack is always a scare resource. A typical call frame (combined size of all local variables) should be less than a kilobyte. A call frame bigger than a megabyte is almost always bad and un-professional.
Upvotes: 1
Reputation: 9144
Limit on maximum stack size controlled with ulimit command. Compiler can (or not) set limit smaller, but not bigger than that.
To see current limit (in kilobytes):
ulimit -s
To remove limit:
ulimit -s unlimited
Upvotes: 1
Reputation:
Yes, there is.
Local arrays are created on the stack, and if your array is too large, the stack will collide with something else in memory and crash the program.
Upvotes: 0