C-分配第二个数组时的分割故障



i退出。这是我有史以来最令人沮丧的事情。即使是非动态INT阵列也会引起segfault。但是,如果我将其声明为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()或执行任何特定的操作,因为这不是完整的代码。这只是我为测试而创建的侧面文件。

说实话,我无法复制:

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 OKn");
    return 0;
}

结果,我认为您的虚拟箱具有一些内存限制,并且您的malloc()失败,请检查其返回值以确保它不是NULL,因此:如何检测Malloc故障?

这是我的版本:

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()您的内存?你尝试过吗?

通常,当使用MPI时,请尝试在连续的存储单元中分配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);
}

正如我在连续内存位置(C)中2D动态阵列中解释的那样。


与您的运行时错误无关:为什么我们需要在C 中使用`int main'而不是`void main'?

相关内容

  • 没有找到相关文章

最新更新