【问题标题】:segmentation fault in dynamic allocation of a 2D array二维数组动态分配中的分段错误
【发布时间】:2014-08-04 16:58:52
【问题描述】:

此代码在 n=10,000 时运行良好,但在具有 2GB 内存的机器上 n=100,000 时运行良好。 在具有 1GB 内存的机器上调用 kswap0 时 n=10,000,但立即显示 n=100,000 的分段错误。

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int **createMatrix(int n)
{
    int **mat=(int**)malloc(n*sizeof(int*));
    int i;
    for(i=0;i<n;i++)
    {
        mat[i]=(int*)malloc(n*sizeof(int));
    }
    return mat;
}
void display(int **mat, int n)
{
    int i,j;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            printf("%d\t",mat[i][j]);
        }
        printf("\n");
    }
}
int main()
{
    int n=100000;
    int **matrixOne=createMatrix(n);
    int **matrixTwo=createMatrix(n);
    int **resultantMatrix=createMatrix(n);
    srand(time(NULL));
    int i,j;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            matrixOne[i][j]=rand()%10;
            matrixTwo[i][j]=rand()%10;
        }
    }
    display(matrixOne,n);
    display(matrixTwo,n);
    int k;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            for(k=0;k<n;k++)
            {
                resultantMatrix[i][j]+=matrixOne[i][k]*matrixTwo[k][j];
            }
        }
    }
    display(resultantMatrix,n);
    for(i=0;i<n;i++)
    {
        free(matrixOne[i]);
        free(matrixTwo[i]);
        free(resultantMatrix[i]);
    }

提前谢谢你!

【问题讨论】:

  • 提示:你需要检查malloc的结果。一旦内存不足,malloc 就会开始返回 NULL
  • BTW 需要初始化 E.g resultantMatrix[i][j]=0;
  • 如果您的设备可以 (a) 分配这么多内存,并且 (b) 拉动 20,000,000,000 以完成 PRNG(我怀疑谁的周期明显短于那个)在不允许您旋转轮胎和粉刷房屋的时间段内,我想要您的硬件。

标签: c arrays dynamic


【解决方案1】:

一个 int 是 4 个字节。在 createMatrix 中,忽略第一个 malloc,您分配了 n * n * sizeof(int) 个字节。对于 n=100,000,这是 40,000,000,000 字节,或大约 40 GB。由于您这样做了 3 次,因此您需要大约 120 GB 的 RAM,而您没有。对于 n = 10,000,您只需要大约 1.2 GB,这是您所拥有的(包括交换空间)。

正如cmets所说,你应该检查malloc的结果以获得更清晰的错误信息,并避免seg错误。

【讨论】:

    【解决方案2】:

    我无法分配内存,因为矩阵对于我的 RAM 来说太大了。每次检查malloc的结果

    int **createMatrix(int n) {
        int **mat = NULL;
        int i;
    
        mat = malloc(n*sizeof(int*));
        if (mat == NULL) {
            exit(1);
        }
        for (i = 0; i<n; i++) {
            mat[i] = malloc(n*sizeof(int));
            if (mat[i] == NULL) {
                exit(2);
            }
        }
        return mat;
    }
    

    【讨论】:

      【解决方案3】:

      这种方法不是内存使用的最佳选择,因为您使用的 RAM 超出了所需。 您将矩阵创建为数组数组,因此对于您分配的每一行,您都有内存开销:

      • 您分配的第一个一维数组不包含数据,而是包含指针。
      • C 运行时库将创建堆元数据

      虽然这有点好,因为您可以像静态二维数组一样编写 M[i][j],但与具有行优先或列优先的传统一维数组相比,您的分配(和解除处理)也会慢得多索引:

      //allocation:
      int * M = malloc(nCol * nRow * sizeof(int));
      
      //access:
      M[i + nRow*j] = data; // Column major
      M[i*nCol + j] = data; // Row major
      
      //deallocation:
      free(M);
      

      http://en.wikipedia.org/wiki/Row-major_order

      最后,数据访问意味着双重取消引用,它可能比行优先或列优先索引更慢。

      【讨论】:

        猜你喜欢
        • 2013-09-04
        • 1970-01-01
        • 2014-01-07
        • 1970-01-01
        • 2015-11-11
        • 2012-08-06
        • 2020-11-23
        • 1970-01-01
        • 2014-06-15
        相关资源
        最近更新 更多