【问题标题】:How to allocate memory for a very large two-dimensional array in C如何在C中为非常大的二维数组分配内存
【发布时间】:2013-03-26 16:28:18
【问题描述】:

我有一个包含 500 万行和 4 列的文件。像往常一样,我尝试读取 500 万乘 4 数组中的数据。

long M = 5000000;
double *coordinates[M];
for (i = 0; i < M; i++){
    coordinates[i] = (double *) calloc(3, sizeof(double));
}

但是当我运行这段代码时,它出现了段错误。在网上搜索了答案后,我知道这是因为堆栈没有那么多内存。如果数组是一维的,有人建议使用 malloc 在堆上分配内存。但我需要一个二维数组,我真的需要这么多内存,我希望有人能帮我解决这个问题。非常感谢。

【问题讨论】:

    标签: c allocation large-data


    【解决方案1】:

    你真的需要额外的指针层吗?

    size_t M = 4321098;
    double (*coordinates)[4] = calloc(M, sizeof *coordinates);
    

    你就完成了。 coordinates[234329][3]=3.1415926535; 一切正常。

    【讨论】:

    • 您的calloc() 呼叫不正确。否则,我喜欢这个答案。
    • @FredLarson:我为 jthill 修复了 calloc,考虑投赞成票(我刚投了一个)。
    • @larsmans:谢谢。我想我也可以纠正它。赞成。
    【解决方案2】:

    你可以改变

    double *coordinates[M];
    

    double **coordinates = malloc(M * sizeof(*coordinates));
    

    确保稍后在程序中free此内存。

    for (i = 0; i < M; i++){
        free(coordinates[i]);
    }
    free(coordinates);
    

    【讨论】:

    • 谢谢。它运作良好。 BTW,既然malloc不能初始化buffer,有没有其他的选择可以同时做分配和初始化?
    • 试试calloc!或 malloc 然后 memcpy
    • @JinYan 你可以使用calloc(M, sizeof(*coordinates))来分配内存并将其初始化为零
    • @simonc 我明白了。非常感谢。
    【解决方案3】:

    正如大家所说,问题在于您试图在函数的堆栈上分配该数组。但是,如果您在代码中将该数组定义为静态怎么办? (就像函数中的全局变量或静态变量?)不必在每次调用函数时都分配它。

    这将避免对 malloc 和 calloc 的调用(以固定大小的数组而不是动态数组为代价)。

    #include <stdio.h>
    #include <stdlib.h>
    #define ROWS 10000000
    #define COLS 4
    double coordinates[ROWS][COLS];
    
    int main() {
    
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                coordinates[i][j] = 1.0;
            }
        }
    
        printf("%.4f\n", coordinates[0][2]);
    
        return 0;
    }
    

    自动变量和静态变量之间的区别在于,自动变量存在于函数内部(可能在每次调用函数时都会分配它们,而静态变量会永远保持其值,并且可能只分配一次)。

    类似的东西。我使用的是 C99,所以你可以用.. c99

    或 gcc -std=c99

    或 CC=c99 制作文件

    另外,在 Linux 中(我也认为在 Windows 中)你可以increase the stack size of your program.

    【讨论】:

      【解决方案4】:

      您试图在堆栈上声明该数组,而不是在导致堆栈溢出错误的堆上。

      试试下面...

      double** coordinates = malloc( sizeof( double* ) * M );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-05
        • 1970-01-01
        • 1970-01-01
        • 2015-02-01
        • 2016-06-21
        相关资源
        最近更新 更多