分配第二个数组时出现分段错误

时间:2016-12-09 19:01:14

标签: c segmentation-fault mpi

我退出了。这是我曾经做过的最令人沮丧的事情。即使是非动态int数组也会导致段错误。但是,如果我将它声明为float / char无论数组,它都可以正常工作。

更新:如果我删除行MPI_Scatter(A[0], N, MPI_INT, A_row, N, MPI_INT, 0, MPI_COMM_WORLD);,它可以正常工作。问题是我需要它......

我正在制作一个节目,但我有一个奇怪的问题。

以下代码正常(如果我们假设 N p 的倍数):

#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"


void main(int argc, char** argv)  
{
   int my_rank, p, N, **A, *diagonals, *A_row;
   MPI_Status status;

   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
   MPI_Comm_size(MPI_COMM_WORLD, &p);

    if (my_rank == 0)  {

        N = 4;
        int *mem = malloc(N * N * sizeof(int));
        A = malloc(N * sizeof(int*));
        for(int i = 0; i < N; i++) 
            A[i] = mem + N*i;    

    }
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);

    A_row = malloc (N * sizeof(int));

    MPI_Scatter(A[0], N, MPI_INT, A_row, N, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Finalize();
}

但是,我需要分配另一个数组(对角线),如下所示:

#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"


void main(int argc, char** argv)  
{
   int my_rank, p, N, **A, *diagonals, *A_row;
   MPI_Status status;

   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
   MPI_Comm_size(MPI_COMM_WORLD, &p);

    if (my_rank == 0)  {

        N = 4;
        int *mem = malloc(N * N * sizeof(int));
        A = malloc(N * sizeof(int*));
        for(int i = 0; i < N; i++) 
            A[i] = mem + N*i;

        diagonals = malloc (N * sizeof(int));    
    }
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);

    A_row = malloc (N * sizeof(int));

    MPI_Scatter(A[0], N, MPI_INT, A_row, N, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Finalize();
}

我得到这个分段错误(如果它有帮助的话):

[teo-VirtualBox:02582] *** Process received signal ***
[teo-VirtualBox:02582] Signal: Segmentation fault (11)
[teo-VirtualBox:02582] Signal code: Address not mapped (1)
[teo-VirtualBox:02582] Failing at address: 0x1
[teo-VirtualBox:02582] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x113d0)[0x7faecc8d23d0]
[teo-VirtualBox:02582] [ 1] a[0x400c85]
[teo-VirtualBox:02582] [ 2] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7faecc511830]
[teo-VirtualBox:02582] [ 3] a[0x4009a9]
[teo-VirtualBox:02582] *** End of error message ***

我错过了一些明显的东西吗?

顺便说一下,我没有使用free(),或者做任何具体的事情,因为这不是完整的代码。它只是我为测试而创建的辅助文件。

1 个答案:

答案 0 :(得分:1)

说实话,我无法重现:

linux21:/home/users/grad1459/Desktop/parallel>mpiexec -np 4 a.out
linux21:/home/users/grad1459/Desktop/parallel>mpicc -Wall -std=c99 main.c
main.c: In function ‘main’:
main.c:9:15: warning: unused variable ‘status’ [-Wunused-variable]
main.c:8:29: warning: variable ‘diagonals’ set but not used [-Wunused-but-set-variable]
linux21:/home/users/grad1459/Desktop/parallel>mpiexec -np 4 a.out
ALL OK
ALL OK
ALL OK
ALL OK
linux21:/home/users/grad1459/Desktop/parallel>

与您的代码非常相似:

#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"


int main(int argc, char** argv)  
{
   int my_rank, p, N, **A, *diagonals, *A_row;
   MPI_Status status;

   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
   MPI_Comm_size(MPI_COMM_WORLD, &p);

    if (my_rank == 0)  {

        N = 4;
        int *mem = malloc(N * N * sizeof(int));
        A = malloc(N * sizeof(int*));
        for(int i = 0; i < N; i++) 
            A[i] = mem + N*i;

        diagonals = malloc (N * sizeof(int));
    }
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);

    A_row = malloc (N * sizeof(int));

    MPI_Scatter(A[0], N, MPI_INT, A_row, N, MPI_INT, 0, MPI_COMM_WORLD);

    MPI_Finalize();
    printf("ALL OK\n");
    return 0;
}

因此,我认为您的虚拟机存在一些内存限制而malloc()失败,检查其返回值以确保它不是NULL,如下所示:How detect malloc failure?

这是我的版本:

linux21:/home/users/grad1459/Desktop/parallel>mpiexec --version
HYDRA build details:
    Version:                                 3.1.3
    Release Date:                            Wed Oct  8 09:37:19 CDT 2014
    CC:                              gcc    
    CXX:                             g++    
    F77:                             gfortran   
    F90:                             gfortran   
    Configure options:                       '--disable-option-checking' '--prefix=/usr/local/mpich3' '--cache-file=/dev/null' '--srcdir=.' 'CC=gcc' 'CFLAGS= -O2' 'LDFLAGS= ' 'LIBS=-lpthread ' 'CPPFLAGS= -I/usr/local/USB/mpich-3.1.3/src/mpl/include -I/usr/local/USB/mpich-3.1.3/src/mpl/include -I/usr/local/USB/mpich-3.1.3/src/openpa/src -I/usr/local/USB/mpich-3.1.3/src/openpa/src -D_REENTRANT -I/usr/local/USB/mpich-3.1.3/src/mpi/romio/include'
    Process Manager:                         pmi
    Launchers available:                     ssh rsh fork slurm ll lsf sge manual persist
    Topology libraries available:            hwloc
    Resource management kernels available:   user slurm ll lsf sge pbs cobalt
    Checkpointing libraries available:       
    Demux engines available:                 poll select

也许问题是你没有free()你的记忆?你试过吗?

通常,在使用时,尝试在连续的内存单元中分配2D动态数组(这样MPI就可以自由地使用它的步幅等)。通常,您可以使用以下函数执行此操作:

int** allocate2D(int** A, const int N, const int M) {
    int i;
    int *t0;

    A = malloc(M * sizeof (int*)); /* Allocating pointers */
    t0 = malloc(N * M * sizeof (int)); /* Allocating data */
    for (i = 0; i < M; i++)
        A[i] = t0 + i * (N);

    return A;
}

void free2Darray(int** p, const int N) {
    free(p[0]);
    free(p);
}

正如我在2D dynamic array in continuous memory locations (C) 中解释的那样。

与运行时错误无关:Why do we need to use `int main` and not `void main` in C++?

相关问题