如何处理大型2D阵列

时间:2012-04-20 16:17:33

标签: c multidimensional-array

我有一个大小为5428x5428的2D数组。它是一个对称数组。但是在编译它时会给我一个错误,说数组大小太大。任何人都可以为我提供一种方式吗?

3 个答案:

答案 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. 将数组从堆栈移动到堆中。

    堆栈的大小限制比堆更严格。

  3. 模拟阵列的某些部分(你说你的是对称的,所以只有1/2的数据是多余的)。

    在你的情况下,数组是对称的,所以不使用数组,而是使用&#34;模拟数组&#34;

    int getArray(array, col, row);
    void setArray(array, col, row, value);

    其中数组是仅保持左下半部分和对角线的数据结构。然后getArray(..)确定列是否大于行,如果是,则返回(注意反转的条目getArray(array, row, col);这利用了数组的对称属性,而不需要实际保持对称侧上。

  4. 使用&#34;仅包含值和#34;

    的值的列表(或树或哈希表)模拟数组

    这对稀疏数组非常有效,因为您不再需要分配内存来保存大量的零(或空)值。如果有人&#34;查找&#34;一个非设定值,你的代码&#34;发现&#34;没有为该条目设置值,然后返回&#34;零&#34;或者没有它实际存储在数组中的空值。

  5. 再次没有更多细节,很难知道什么样的解决方案是最好的方法。

答案 2 :(得分:1)

当您创建局部变量时,它们会进入堆栈,该堆栈的大小有限。你正在超越这个极限。

您希望阵列进入堆,这是您的系统所具有的所有虚拟内存,即现代系统上的演出和演出。管理它有两种方法。一种是动态分配数组,如k06a的答案;使用malloc()或特定于平台的分配器函数(例如Windows上的GlobalAlloc())。第二种是在任何函数之外将数组声明为全局或模块静态变量。

使用全局或静态的缺点是将在程序的整个生命周期内分配此内存。而且,几乎每个人都原则上讨厌全局变量。另一方面,你可以使用二维数组语法“array [x] [y]”等来访问数组元素......比做数组[x + y * width]更容易,加上你不要不得不记住你是否应该做“x + y * width”或“x * height + y”。