我有一个大小为5428x5428的2D数组。它是一个对称数组。但是在编译它时会给我一个错误,说数组大小太大。任何人都可以为我提供一种方式吗?
答案 0 :(得分:3)
这个数组对于程序堆栈内存来说很大 - 这就是你的错误。
int main()
{
double arr[5428][5428]; // 8bytes*5428*5428 = 224MB
// ...
// use arr[y][x]
// ...
// no memory freeing needed
}
使用动态数组分配:
int main()
{
int i;
double ** arr;
arr = (double**)malloc(sizeof(double*)*5428);
for (i = 0; i < 5428; i++)
arr[i] = (double*)malloc(sizeof(double)*5428);
// ...
// use arr[y][x]
// ...
for (i = 0; i < 5428; i++)
free(arr[i]);
free(arr);
}
或者分配大小为MxN
的普通数组并使用ptr[y*width+x]
int main()
{
double * arr;
arr = (double*)malloc(sizeof(double)*5428*5428);
// ...
// use arr[y*5428 + x]
// ...
free(arr);
}
或使用组合方法:
int main()
{
int i;
double * arr[5428]; // sizeof(double*)*5428 = 20Kb of stack for x86
for(i = 0; i < 5428; i++)
arr[i] = (double)malloc(sizeof(double)*5428);
// ...
// use arr[y][x]
// ...
for(i = 0; i < 5428; i++)
free(arr[i]);
}
答案 1 :(得分:1)
当数组变大时,有许多解决方案。对你有益的一个在很大程度上取决于你实际在做什么。
我列出了一些让你思考的问题:
购买更多内存。
将数组从堆栈移动到堆中。
堆栈的大小限制比堆更严格。
模拟阵列的某些部分(你说你的是对称的,所以只有1/2的数据是多余的)。
在你的情况下,数组是对称的,所以不使用数组,而是使用&#34;模拟数组&#34;
int getArray(array, col, row);
void setArray(array, col, row, value);
其中数组是仅保持左下半部分和对角线的数据结构。然后getArray(..)确定列是否大于行,如果是,则返回(注意反转的条目getArray(array, row, col);
这利用了数组的对称属性,而不需要实际保持对称侧上。
使用&#34;仅包含值和#34;
的值的列表(或树或哈希表)模拟数组这对稀疏数组非常有效,因为您不再需要分配内存来保存大量的零(或空)值。如果有人&#34;查找&#34;一个非设定值,你的代码&#34;发现&#34;没有为该条目设置值,然后返回&#34;零&#34;或者没有它实际存储在数组中的空值。
再次没有更多细节,很难知道什么样的解决方案是最好的方法。
答案 2 :(得分:1)
当您创建局部变量时,它们会进入堆栈,该堆栈的大小有限。你正在超越这个极限。
您希望阵列进入堆,这是您的系统所具有的所有虚拟内存,即现代系统上的演出和演出。管理它有两种方法。一种是动态分配数组,如k06a的答案;使用malloc()或特定于平台的分配器函数(例如Windows上的GlobalAlloc())。第二种是在任何函数之外将数组声明为全局或模块静态变量。
使用全局或静态的缺点是将在程序的整个生命周期内分配此内存。而且,几乎每个人都原则上讨厌全局变量。另一方面,你可以使用二维数组语法“array [x] [y]”等来访问数组元素......比做数组[x + y * width]更容易,加上你不要不得不记住你是否应该做“x + y * width”或“x * height + y”。