2

在我的 C 代码中,我为 2d 数组分配内存,double E[2000][2000];但是当我运行它时会出现运行时错误Segmentation fault(core dumped),并且当我将数组大小减小到 900 左右时,代码运行良好。

为什么它显示运行时错误,因为双占用 64 位内存(IEEE 标准)所以代码应该占用大约 32MB,这与 ram 大小相比并不多。如果 C 不支持它,那么如果我的最大数量应该如何进行我必须存储的数据是 4000000,每个都是浮点数。

4

3 回答 3

6

您是否将 E 声明为局部变量?如果是这样,你的堆栈内存就用完了。

void func()
{
    double E[2000][2000]; /// definitely an overflow
}

使用动态分配:

double* E = malloc(2000 * 2000 * sizeof(double));
/// don't forget to "free(E);"  later

或者,如果您需要二维数组,请使用之字形:

double** E = malloc(2000 * sizeof(double*));

/* check that the memory is allocated */
if(!E)
{
    /* do something like exit(some_error_code);  to terminate your program*/
}

for(i = 0 ; i < 2000 ; i)
{
      E[i] = malloc(2000 * sizeof(double));

     /* check that the memory for this row is allocated */
     if(!E[i])
     {
        /* do something like exit(some_error_code);  to terminate your program*/
     }
}

那么释放就稍微复杂一点:

for(i = 0 ; i < 2000 ; i)
{
      free(E[i]);
}

free(E);

PS 如果你想以连续的方式保存所有数据,有一个技巧(代码来自Takuy​​a Ooura 的 FFT 包

double **alloc_2d(int n1, int n2)
{
    double **ii, *i;
    int j;

    /* pointers to rows */
    ii = (double **) malloc(sizeof(double *) * n1);

    /* some error checking */
    alloc_error_check(ii);

    /* one big memory block */
    i = (double *) malloc(sizeof(double) * n1 * n2);

    /* some error checking */
    alloc_error_check(i);

    ii[0] = i;
    for (j = 1; j < n1; j++) {
        ii[j] = ii[j - 1] + n2;
    }
    return ii;
}

void free_2d(double **ii)
{
    free(ii[0]);
    free(ii);
}

你刚打电话

double** E = alloc2d(2000, 2000);

free_2d(E);
于 2012-10-02T10:04:02.057 回答
5

我假设您只是通过简单地在堆栈上分配它

double E[2000][2000];

这可能会超过分配给您的程序的堆栈大小。

尝试使用 malloc(或 c++ 中的新功能)或使用选项增加程序的默认堆栈大小。为此,可以使用 setrlimit() 配置 gcc。

在 gcc 中设置堆栈大小

请记住,即使堆栈大小增加,这个大小的数组也应该是全局的

如果一维大小固定,您还可以使用单个语句在堆上分配二维数组

double (* E)[COLUMN_SIZE];
int rows = 20; // this is dynamic and can be input from user at run time
E = malloc(rows * sizeof(*E)); // this needs to be freed latter

一个更详细的类似示例 ,在没有循环的情况下分配 2d 数组

于 2012-10-02T10:04:46.737 回答
0

这取决于您分配数组的位置。使用堆栈空间可能会导致溢出(除非您让链接器分配一个额外的大堆栈)。

例如,这可能不起作用

int main()
{
    double E[2000][2000];   // Likely an overflow
}

但是,将数组移动到静态内存区域

double E[2000][2000];

int main()
{
   // use E here
}

可能会避免这个问题。

于 2012-10-02T17:03:58.647 回答