Zeta.Investigator
Zeta.Investigator

Reputation: 973

Is there any limitation of array length in C?

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

Answers (3)

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

Leonid Volnitsky
Leonid Volnitsky

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

user529758
user529758

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

Related Questions