C中的数组的最大索引大小为2048吗?

问题描述 投票:0回答:1

我写了一段使用大小为3000的静态数组的代码。

通常,我只会使用for循环来扫描3000个值,但是看来我最多只能扫描2048个数字。对我来说,这似乎是内存分配的问题,但我不确定。

出现问题是因为我不希望用户输入他们打算输入的数字数量。他们只应输入所需数量的数字,输入0终止扫描,然后程序开始工作。 (否则,我只使用malloc。)

该代码是一个相当简单的数字出现计数器,位于以下位置:

int main(int argc, char **argv)
{

int c;
int d;
int j = 0;
int temp;
int array[3000];
int i;

// scanning in elements to array (have just used 3000 because no explicit value for the length of the sequence is included) 
for (i = 0; i < 3000; i++)
{
    scanf("%d", &array[i]);
    if (array[i] == 0)
    {
        break;
    }
}

// sorting
for(c = 0; c < i-1; c++)    { 
    for(d = 0; d < i-c-1; d++)  {
        if(array[d] > array[d+1])   { 
            temp        = array[d]; // swaps
            array[d]    = array[d+1];
            array[d+1]  = temp;
        }
    }
}

int arrayLength = i + 1; // saving current 'i' value to use as 'n' value before reset

for(i = 0; i < arrayLength; i = j)
{
    int numToCount = array[i];
    int occurrence = 1; // if a number has been found the occurence is at least 1
    for(j = i+1; j < arrayLength; j++) // new loops starts at current position in array +1 to check for duplicates
    {
        if(array[j] != numToCount) // prints immediately after finding out how many occurences there are, else adds another
        {
            printf("%d: %d\n", numToCount, occurrence); 
            break; // this break keeps 'j' at whatever value is NOT the numToCount, thus making the 'i = j' iterator restart the process at the right number
        } else {
            occurrence++;
        }
    }
}

return 0;
}

此代码对于2048以下的任何数量的输入都非常有效。输入以下示例将不起作用:1000 1s,1000 2s和1000 3s,之后程序将输出:

1: 1000
2: 1000
3: 48

我的问题是是否有任何方法可以解决此问题,以便程序输出正确的出现次数。

c arrays memory-management size
1个回答
0
投票

回答您的标题问题:C中数组的大小(理论上)仅受size_t变量可以表示的最大值的限制。这通常是32位或64位无符号整数,因此(对于32位情况)您可以拥有超过20亿个元素(在64位系统中则更多,甚至更多)。

但是,您在代码中可能遇到的是对程序可用内存的限制,其中行int array[3000];声明了automatic变量。这些空间通常在stack上分配-这是在调用函数(或main)时分配的有限大小的内存块。该内存的大小有限,并且在您的情况下(假定为32位4字节整数),您要从堆栈中取出12,000字节,这可能会引起问题。

有两种(也许更多?)解决问题的方法。首先,您可以声明数组static-这将使编译器预先分配内存,因此在运行时无需从堆栈中取出它:

static int array[3000];

第二种可能更好的方法是调用malloc为数组分配内存;这从heap分配内存-在几乎所有系统上,该内存都比堆栈大得多。它通常仅受操作系统的可用虚拟内存限制(在大多数现代PC上为数GB):

int *array = malloc(3000 * sizeof(int));

[此外,使用malloc的优点在于,如果由于某种原因没有足够的可用内存,则该函数将返回NULL,您可以对此进行测试。您可以用相同的方式访问数组的元素,例如使用array[i]。当然,您应该确保在使用完函数后将其释放:

free(array);

((当您退出程序时,这将自动完成,但是这是很好的编码风格,可以习惯于明确地执行它!)

© www.soinside.com 2019 - 2024. All rights reserved.