You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MPI C语言代码仅输出矩阵最后一行的问题排查与修正

MPI生成倍数矩阵错误分析与修正

问题背景

编写MPI程序生成每行元素为对应行号倍数的矩阵(如第一行1 2 3 4,第二行2 4 6 8等),但实际运行后所有行均为最后一行内容(4 8 12 16)。

原代码

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


int main (int argc, char **argv)
{
    int num_procs;
    int rank;
    int n;
    int lst[n];
    // int lst2[n];
    int matrix[n][n];

    MPI_Status status;

    MPI_Init(&argc, &argv); 
    MPI_Comm_size (MPI_COMM_WORLD, &num_procs); 
    MPI_Comm_rank (MPI_COMM_WORLD, &rank); 
    //printf("%d: hello (p=%d)\n", rank, num_procs);
    
    n=num_procs;

    if (rank==0){

        for (int i=0;i<n;i++) {
            lst[i]=(i+1)*(rank+1);
            // printf("%d ",lst[i]);
        }
        // printf("\n");

        for (int i=0;i<n;i++){
            matrix[0][i]=lst[i];
        }

        for (int k=1;k<num_procs;k++){
            MPI_Recv(&lst,n,MPI_INT,k,0,MPI_COMM_WORLD,&status);
            
            for (int j=0;j<n;j++){
                matrix[k][j]=lst[j];
            }

            // for (int i=0;i<n;i++) {
            //     printf("%d ",lst[i]);
            // }
            // printf("\n");
        }

        for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                printf("%d ", matrix[i][j]);
                if (j==n-1){printf("\n");}
            }
        }
    }
    else{
        for (int i=0;i<n;i++) {
            lst[i]=(i+1)*(rank+1);
            // printf("%d ",lst[i]);
        }
        // printf("\n");

        MPI_Send(&lst[0],n,MPI_INT,0,0,MPI_COMM_WORLD);
    }
    
    MPI_Finalize();
}

实际输出

4 8 12 16 
4 8 12 16 
4 8 12 16 
4 8 12 16 

期望输出

1 2 3 4 
2 4 6 8 
3 6 9 12 
4 8 12 16 

错误原因

核心问题是变长数组(VLA)的初始化顺序错误:

  • 定义lst[n]和matrix[n][n]时,变量n尚未被赋值(此时n是未初始化的垃圾值)。
  • C语言中变长数组的大小必须在定义时确定,后续给n赋值num_procs不会改变已分配的数组内存大小,属于未定义行为。
  • 这种错误导致内存布局混乱,后续的赋值、MPI通信操作会破坏矩阵内存,最终所有行被最后一次写入的数据覆盖。

修正方法

调整变量初始化顺序,确保在定义变长数组前n已经被正确赋值:

  1. 将n=num_procs;移到变长数组定义之前;
  2. 遵循MPI初始化→获取进程数→给n赋值→定义变长数组的顺序。

修正后的代码

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


int main (int argc, char **argv)
{
    int num_procs;
    int rank;
    int n;

    MPI_Status status;

    MPI_Init(&argc, &argv); 
    MPI_Comm_size (MPI_COMM_WORLD, &num_procs); 
    MPI_Comm_rank (MPI_COMM_WORLD, &rank); 
    
    // 先给n赋值,再定义变长数组
    n=num_procs;
    int lst[n];
    int matrix[n][n];

    if (rank==0){

        for (int i=0;i<n;i++) {
            lst[i]=(i+1)*(rank+1);
        }

        for (int i=0;i<n;i++){
            matrix[0][i]=lst[i];
        }

        for (int k=1;k<num_procs;k++){
            MPI_Recv(&lst,n,MPI_INT,k,0,MPI_COMM_WORLD,&status);
            
            for (int j=0;j<n;j++){
                matrix[k][j]=lst[j];
            }
        }

        for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                printf("%d ", matrix[i][j]);
                if (j==n-1){printf("\n");}
            }
        }
    }
    else{
        for (int i=0;i<n;i++) {
            lst[i]=(i+1)*(rank+1);
        }

        MPI_Send(&lst[0],n,MPI_INT,0,0,MPI_COMM_WORLD);
    }
    
    MPI_Finalize();
}

验证结果

运行修正后的代码,将得到符合预期的输出:

1 2 3 4 
2 4 6 8 
3 6 9 12 
4 8 12 16 

内容的提问来源于stack exchange,提问作者S K Shree Ram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 04:32:30