2017-09-03 43 views
-4

首先,here is my code只是爲了讓你能夠跟上。C中的數組大小是否有限制?

#include <stdio.h> 
#include <stdlib.h> 

#define MAX 10000000 

long long min(long long a, long long b, long long c) { 

    long long temp_min = a; 
    if (b < temp_min) temp_min = b; 
    if (c < temp_min) temp_min = c; 

    return temp_min; 

} 

long long numOp (long long n, long long memo[]) { 

    memo[1] = 0; 

    for (int i = 2; i <= n; i++) { 

     long long guess_1 = MAX, guess_2 = MAX, guess_3 = MAX; 

     guess_1 = memo[i - 1] + 1; 

     if (i % 2 == 0) guess_2 = memo[i/2] + 1; 

     if (i % 3 == 0) guess_3 = memo[i/3] + 1; 

     memo[i] = min(guess_1, guess_2, guess_3); 

    } 

    return memo[n]; 

} 

int main (void) { 
    // Read the input from the user 
    long long n, v = 0, N; 
    scanf ("%lld", &n); 
    N = n; 

    long long num_operations[n + 1]; 
    long long sequence[n]; 

    for (long long i = 1; i <= n; i++) { 
     num_operations[i] = -1; 
    } 

    for (long long l = 0; l < n; l++) { 
     sequence[l] = -1; 
    } 

    // Compute the minimum number of operations required to get to n starting form 1 
    long long op = numOp (n, num_operations); 

    // Print the result 
    printf ("%lld\n", op); 

    sequence[v++] = n; 
    while (n > 1) { 

     if (num_operations[n - 1] < num_operations[n]) { 

      //printf("%lld ", n - 1); 
      sequence[v++] = n - 1; 
      n = n - 1; 

     } else { 

      long long temp1 = -1, 
         temp2 = -1; 

      if (n % 2 == 0) { 
       temp1 = num_operations[n/2]; 
      } 

      if (n % 3 == 0) { 
       temp2 = num_operations[n/3]; 
      } 

      if (temp2 < temp1) { 

       //printf("%lld ", n/2); 
       sequence[v++] = n/2; 
       n = n/2; 

      } else { 

       //printf("%lld ", n/3); 
       sequence[v++] = n/3; 
       n = n/3; 

      } 
     } 
    } 

    // Print the intermediate numbers from 1 up through n 
    for (long long k = N - 1; k >= 0; k--) { 
     if (sequence[k] != -1) 
      printf("%lld ", sequence[k]); 
    } 
    printf("\n"); 

    return 0; 
} 

所以我正在處理這個問題,輸入n使得n介於1和1,000,000之間。該程序在輸入量高達100,000的情況下運行良好,但一旦命中(甚至低於)1,000,000,我就會遇到分段錯誤。

爲了縮小可能性,我調試了程序,發現分段錯誤發生在第52行,我嘗試訪問數組元素。

我唯一的猜測是,對於C語言中的數組有多大可以獲得某種限制,如果是這樣的話,你們是否知道任何方法?

+1

請將此處的代碼,錯誤,樣本數據或文本輸出以純文本的形式發佈,而不是以難以閱讀的圖像的形式發佈,不能複製粘貼以幫助測試代碼或在答案中使用,並且不利於那些使用屏幕閱讀器的人。您可以編輯您的問題以在問題的正文中添加代碼。使用'{}'按鈕來格式化任何代碼塊,或使用四個空格縮進以獲得相同的效果。 – tadman

+2

是:它是42 ... – wildplasser

+2

除了'size_t'的限制外,C沒有限制。有一個由您的操作系統設置的分配限制(32位?64位?ulimit?設置?)。 – tadman

回答

1

您正在使用VLA s作爲分配在您的call stack上的自動變量。所以你受限於調用堆棧的最大大小(通常只有幾兆字節,細節是操作系統和計算機的具體情況)。

您應該將這些分配到堆上。閱讀關於C dynamic memory allocation。所以代碼,而不是

long long *num_operations = calloc (n + 1, sizeof(long long)); 
long long *sequence = calloc(n, sizeof(long long)); 

不要忘了測試的calloc失敗:

if (!num_operations) 
    { perror("num_operations calloc"); exit(EXIT_FAILURE); } 

且同樣callocsequence

不要在年底忘記free(如您的main

free (num_operations); 
free (sequence); 

以避免memory leaks(使用valgrind來調試這些)。在你的特定情況下,你可能不是free,因爲程序(在Linux或Windows等上)的virtual address space在其process結束時被刪除。

FYI malloccalloc,和free使用system calls,如mmap(2),改變虛擬地址空間。但通常C標準庫不會向OS釋放(使用munmapfree -d內存,但將其標記爲未來malloc-s或calloc -s可重用。

在實踐中,一旦不需要內存,您將更好地使用free內存(因此您經常可以在同一例程中使用callocfree)。閱讀關於garbage collection技術,概念和術語是值得的。

當然,堆分配的內存也是有限的(因爲你的計算機有限的資源),但限制可能取決於計算機,通常要大得多(至少在筆記本電腦上的千兆字節,在超級計算機上可能是兆兆字節)。即使資源耗盡(這是我通常禁用的操作系統功能),有時calloc似乎也能正常工作(請閱讀memory overcommitment)。在POSIX和Linux系統上,setrlimit(2)可用於降低(或更改一點)該限制。

1

當然,因爲指數不能大於SIZE_MAX。但是當你在堆棧中分配自動變量時,這不是問題。堆棧的大小非常有限。您可以使用malloc函數系列在堆上分配更多內容。當然,您受限於您的程序堆可用

+1

*堆棧的大小有所不同。您可以使用'malloc'系列函數在堆上分配更多內容。*這可能會也可能不會。 【舉例】(https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/5/html/Tuning_and_Optimizing_Red_Hat_Enterprise_Linux_for_Oracle_9i_and_10g_Databases/sect-Oracle_9i_and_10g_Tuning_Guide-Growing_the_Oracle_SGA_to_2.7_GB_in_x86_Red_Hat_Enterprise_Linux_2.1_Without_VLM-Linux_Memory_Layout.html),Linux 32位方法具有堆的sbrk()'部分最多1 GB左右,堆棧和堆的'mmap()'部分最多2 GB。 –

+1

在大多數linuxem上,我知道堆棧默認限制爲8MB。你可以檢查它(並改變當然)ulimit -s –

相關問題