2012-07-28 75 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