3

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

4

3 回答 3

4

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

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]);
}
于 2012-04-20T16:46:03.193 回答
1

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

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

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

于 2012-04-20T16:59:05.113 回答
1

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

我将列出一些让您思考:

  1. 购买更多内存。

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

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

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

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

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

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

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

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

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

于 2012-04-20T16:39:25.803 回答