无法在C中分配内存

时间:2018-06-29 13:59:44

标签: c arrays out-of-memory

我想定义一个3D数组/指针来存储我的计算结果:

#include <stdio.h>

int main(void) {
    float ***ww;
    int i, j, k;
    int n1 = 3000, n2 = 6000, n3 = 9000;
    ww = floatalloc3(n1, n2, n3); /* floatalloc3 is a self-defined function used to allocate memory space for 3D array/pointer */
    for (i = 0; i < n1; i++) {
        for (j = 0; j < n2; j++) {
            for (k = 0; k < n3; k++) {
                ww[i][j][k] = 0.0;
            }
        }
    }
    free(**ww);
    free(*ww);
    free(ww);
    return 0;
}

cannot allocate 648000000000 bytes: Cannot allocate memory弹出错误。那我怎么解决这个问题呢?

是否可以拆分数据并将其存储到不同的内核?

3 个答案:

答案 0 :(得分:3)

您要分配大约3000 * 6000 * 9000 * 4个字节的数据,即〜 648GB 有点

答案 1 :(得分:3)

您试图分配的内存量似乎是巨大的:6,480亿字节加上2个间接级别的开销!您的系统可能不允许您分配那么多的内存。

您应该测试floatalloc3的返回值以检测分配失败。实际上,发布此自定义函数的源代码以确认其正确性将很有用。

还请注意,这3个free调用可能不足以释放分配的块,但是如果没有floatalloc3的源代码,则只能推测。

答案 2 :(得分:2)

如果您确实打算计算3000×6000×9000个浮点值(162,000,000,000个值),则需要重新考虑您的方法。

有几种方法,但是最典型的方法是将任务分成较小的部分,然后逐个计算。

如果网格几乎是空的,但是您需要以不可预测的方式访问它(使分割任务变得不可取),则可以使用特定于OS的方法来对数据集进行内存映射。 (不过,您确实需要一个64位OS来对此特定数据集执行此操作;并且您还需要在某些文件系统上有足够的存储空间来存储数据。)我已在2011年的另一篇Linux中展示了如何做到这一点。论坛here;此示例程序处理了一个TB级的内存映射数据集,几乎是OP正在考虑的数据集大小的两倍。

无论如何,您绝对不希望使用两级间接访问数据。这严重破坏了当前CPU预测和缓存访问的能力,并会导致性能下降。相反,您应该使用线性数据结构。例如:

size_t  xsize;
size_t  ysize;
size_t  zsize;
float  *cells;

#define  CELL(x,y,z)  cells[(x) + xsize*( (y) + ysize * (z) )]

换句话说,网格中每个单元格的索引为(x) + (y)*xsize + (z)*xsize*ysize。不仅数据然后在内存中是连续的(这对于缓存很重要),而且CPU(和您的编译器)还可以根据访问模式更好地预测将来的访问。