【问题标题】:Why do I get a segmentation fault when I allocate memory for a matrix?为什么在为矩阵分配内存时会出现分段错误?
【发布时间】:2014-09-06 02:39:30
【问题描述】:

我正在开发一个带有矩阵的 MPI 程序。我在每个过程中需要 5 个矩阵。当我创建第 5 个矩阵时,出现分段错误。

以下是一些截图:

在这里它起作用了,当 sPrevParts 矩阵被注释掉时

这里出现了分段错误! :秒 这里又是分段错误......

这是这部分代码(如果需要完整代码,请告诉我)。

MATRIX_CREATE 函数

    /* M(m*n) as array of rows, call free(p) */
    void **matrix_create(size_t m, size_t n, size_t size) {
       size_t i; 
       void **p= (void **) malloc(m*n*size+ m*sizeof(void *));
       char *c=  (char*) (p+m);
       for(i=0; i<m; ++i)
          p[i]= (void *) c+i*n*size;
       return p;
    }

主要

    /* Variables for the partial matrixes */
    double **aParts, **mParts, **mPrevParts, **sParts, **sPrevParts;
    /* Gets the rows of the partial matrixes of each process */
    rows = sendcounts[myrank] / n;
    /* Allocates memory for the partial A matrix of each process */
    aParts = (double**)matrix_create(rows, n, sizeof(double));
    /* Allocates memory for the partial M matrix of each process */
    mParts = (double**)matrix_create(rows, n, sizeof(double));
    /* Allocates memory for the partial S matrix of each process */
    sParts = (double**)matrix_create(rows, n, sizeof(double));
    /* Allocates memory for the previous partial M matrix of each process */
    mPrevParts = (double**)matrix_create(rows, n, sizeof(double));
    /* Allocates memory for the previous partial S matrix of each process */
    //PrevParts = (double**)matrix_create(rows, n, sizeof(double));

    MPI_Barrier(MPI_COMM_WORLD);

    /* Scatters the A matrix through all the processes */
    MPI_Scatterv(&a[0][0], sendcounts, displs, MPI_DOUBLE, &aParts[0][0], sendcounts[myrank], MPI_DOUBLE, root, MPI_COMM_WORLD);        
    /* Scatters the M matrix through all the processes */
    MPI_Scatterv(&m[0][0], sendcounts, displs, MPI_DOUBLE, &mParts[0][0], sendcounts[myrank], MPI_DOUBLE, root, MPI_COMM_WORLD);
    MPI_Scatterv(&m[0][0], sendcounts, displs, MPI_DOUBLE, &mPrevParts[0][0], sendcounts[myrank], MPI_DOUBLE, root, MPI_COMM_WORLD);
    /* Scatters the S matrix through all the processes */
    MPI_Scatterv(&s[0][0], sendcounts, displs, MPI_DOUBLE, &sParts[0][0], sendcounts[myrank], MPI_DOUBLE, root, MPI_COMM_WORLD);
    //MPI_Scatterv(&s[0][0], sendcounts, displs, MPI_DOUBLE, &sPrevParts[0][0], sendcounts[myrank], MPI_DOUBLE, root, MPI_COMM_WORLD);

    int i;
    for (i = 0; i < npes; ++i) {
        MPI_Barrier(MPI_COMM_WORLD);
        if (myrank == i) {
            printf("%d\n", i);
            matrix_print(aParts, rows, n, "aParts");
            matrix_print(mParts, rows, n, "mParts");
            matrix_print(sParts, rows, n, "sParts");
            matrix_print(mPrevParts, rows, n, "mPrevParts");
        }
    }

注意:这是由所有进程运行的。

难道我的内存都用完了?我怎样才能解决这个问题?谢谢

【问题讨论】:

  • 您总是希望从查看/共享所有段错误的堆栈跟踪开始。另请注意,没有证据并不是没有证据;这意味着当没有引发段错误时,您仍然可以(很可能)进行无效的内存访问。请确保使用您的开发工具(无论是 Valgrind、Visual Studio 还是您拥有的)来报告所有访问违规。
  • 您需要对问题应用“二分查找”。作为打印语句,直到您发现导致问题的 ONE。然后开始删除部件,直到你有一个仍然崩溃的小程序。发布该程序。
  • 感谢您的回答。问题出在 Scatterv 上。我不知道如何解决这个问题。矩阵根本不会分散。我删除了一些代码并且它可以工作,但我需要注释掉的东西。这些 Scatterv 是怎么回事?再次感谢。 ://

标签: c memory matrix segmentation-fault mpi


【解决方案1】:

void * 赠送:

malloc(m*n*size+ m*sizeof(void *));

您从未真正分配您的矩阵,而只是分配一个二维指针数组,然后您将其视为double 的数组。

  1. 永远不要那样做。
  2. 您可能正在使用 32 位运行时进行开发,其中您的指针只有 double 大小的一半(或其他类型的系统,其中指针只是小于 double)。

请参考this example,获取有关在使用MPI 时如何使用矩阵的基本参考。

【讨论】:

  • 嗨@Domi。感谢您的回答,但我仍然不知道我的 MPI_Scatterv 操作发生了什么。 :s 顺便说一句,我不明白如何改变你提到的“void *”的东西。你能解释得更好吗?再次感谢。
  • 说实话,现在我再看一遍,这不是问题。我可能不得不收回我的答案。从您的问题来看,这听起来不是您的代码,而且您不太清楚自己在做什么。也许您想从头开始,使用您尝试做的更简单的版本。单个malloc 数组实际上分配了矩阵,此外,还分配了指向每一行的指针数组。考虑一下Tutorial on Scatter & Gather,确保您在正确的位置获得正确的数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
相关资源
最近更新 更多