【问题标题】:how to deal with large 2D arrays如何处理大型二维数组
【发布时间】:2012-04-20 16:17:33
【问题描述】:

我有一个大小为 5428x5428 大小的二维数组。它是一个对称数组。但是在编译时它给了我一个错误,说数组大小太大。谁能给我一个方法?

【问题讨论】:

  • 如果你分享你的代码(或更简单的版本)并提供编译器给你的错误会更好。
  • 嗯,它是这样的.. void main() { double array[5428][5428]; ..... } 当我编译它时,它在声明行给我一个错误,说数组大小太大。
  • 这取决于你的电脑内存大小。

标签: c multidimensional-array


【解决方案1】:

这个数组对于程序堆栈内存来说太大了 - 那是你的错误。

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]);
}

【讨论】:

  • 您也可以使用double (*arr)[5248] = malloc (sizeof *arr * 5248); -- 内存将被分配为单个连续块,您可以将其作为普通二维数组进行索引。
  • 谢谢,我会在回答中添加这个案例,好吗?
  • @JohnBode - 但这仅在您有一个连续的 5k*5k 可用内存块时才有效。通过执行一系列行,您可以处理内存碎片。虽然 64 位并购买大量 RAM 会有所帮助!
【解决方案2】:

当数组变大时,有多种解决方案。对你有好处的方法在很大程度上取决于你实际在做什么。

我会列出一些让你思考的:

  1. 购买更多内存。

  2. 将数组从堆栈移动到堆。

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

  3. 模拟数组的一部分(你说你的是对称的,所以只有不到 1/2 的数据是多余的)。

    在您的情况下,数组是对称的,因此不要使用数组,而是使用“模拟数组”

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

    其中数组是一个数据结构,它只保存左下半部分和对角线。 getArray(..) 然后确定列是否大于行,如果是,则返回(注意颠倒的条目getArray(array, row, col); 这利用了数组的对称属性,而无需实际保持对称边。

  4. 使用“仅包含值的项”的列表(或树或哈希表)模拟数组

    这对于稀疏数组非常有效,因为您不再需要分配内存来保存大量零(或空)值。如果有人“查找”未设置的值,您的代码会“发现”没有为该条目设置的值,然后返回“零”或空值,而不会将其实际存储在您的数组中。

同样没有更多细节,很难知道哪种解决方案是最好的方法。

【讨论】:

    【解决方案3】:

    当您创建局部变量时,它们会进入堆栈,堆栈的大小是有限的。你正在突破这个限制。

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

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

    【讨论】:

      猜你喜欢
      • 2014-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 2017-09-20
      • 1970-01-01
      相关资源
      最近更新 更多