我写了一段使用大小为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
中数组的大小(理论上)仅受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);
((当您退出程序时,这将自动完成,但是这是很好的编码风格,可以习惯于明确地执行它!)