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

C语言双指针传参实现矩阵乘法出现段错误的问题求助

问题分析与修复

核心问题1:二维数组与int**的类型不匹配

你在main里定义的是变长二维数组(VLA),比如int matrixA[M][N],它在内存中是连续存储的一块区域,当它退化为指针时,类型是int (*)[N](指向包含N个int的数组的指针),而不是int**。

你强制把matrixA转成int**传给multiply函数后,函数里执行*(matrixA + j)时,会把matrixA起始地址处的4/8字节(int的大小)当成一个指针地址去访问——但这其实是数组里的第一个元素值,不是合法指针,直接触发段错误。

核心问题2:矩阵乘法的索引逻辑错误

你的三重循环里,矩阵乘法的元素索引写错了:
正确的矩阵乘法应该是matrixC[i][j] = sum(matrixA[i][k] * matrixB[k][j]),但你写成了matrixA[j][k] * matrixB[k][j],这会导致计算结果完全错误,即使没有段错误也得不到正确结果。


修复方案(两种可选)

方案1:直接使用变长数组(VLA)作为函数参数

这是最贴合你现有代码的方案,不需要修改数组定义,只需要调整函数参数类型:

// 修改函数参数为VLA类型
void multiply(int M, int N, int K, int matrixA[M][N], int matrixB[N][K], int matrixC[M][K]){
    for (int i = 0; i < M; i++){
        for (int j = 0; j < K; j++){
            int sum = 0;
            for (int k = 0; k < N; k++){
                // 修正索引逻辑
                sum += matrixA[i][k] * matrixB[k][j];
            }
            matrixC[i][j] = sum;
        }
    }
}

int main(){
    int M, N, K;
    scanf("%d%d%d", &M, &N, &K);
    int matrixA[M][N];
    int matrixB[N][K];
    int matrixC[M][K];
    
    // 输入矩阵A
    for(int i=0; i<M; i++){
        for(int j=0; j<N; j++){
            scanf("%d", &matrixA[i][j]); // 改成&更直观,原写法也合法但可读性差
        }
    }

    // 输入矩阵B
    for(int i=0; i<N; i++){
        for(int j=0; j<K; j++){
            scanf("%d", &matrixB[i][j]);
        }
    }

    // 直接传递数组,无需强制类型转换
    multiply(M, N, K, matrixA, matrixB, matrixC);
    
    // 输出结果
    for(int i=0; i<M; i++){
        for(int j=0; j<K; j++){
            printf("%d ", matrixC[i][j]);
        }
        printf("\n");
    }
    return 0;
}

方案2:使用动态分配的int**二维数组

如果需要更灵活的内存管理(比如数组大小在运行时动态调整且不想用VLA),可以手动分配指针数组和每行的内存:

#include <stdlib.h> // 需要malloc/free

void multiply(int M, int N, int K, int **matrixA, int **matrixB, int **matrixC){
    for (int i = 0; i < M; i++){
        for (int j = 0; j < K; j++){
            int sum = 0;
            for (int k = 0; k < N; k++){
                sum += matrixA[i][k] * matrixB[k][j];
            }
            matrixC[i][j] = sum;
        }
    }
}

int main(){
    int M, N, K;
    scanf("%d%d%d", &M, &N, &K);
    
    // 动态分配matrixA
    int **matrixA = malloc(M * sizeof(int*));
    for(int i=0; i<M; i++){
        matrixA[i] = malloc(N * sizeof(int));
    }
    
    // 动态分配matrixB
    int **matrixB = malloc(N * sizeof(int*));
    for(int i=0; i<N; i++){
        matrixB[i] = malloc(K * sizeof(int));
    }
    
    // 动态分配matrixC
    int **matrixC = malloc(M * sizeof(int*));
    for(int i=0; i<M; i++){
        matrixC[i] = malloc(K * sizeof(int));
    }
    
    // 输入矩阵A
    for(int i=0; i<M; i++){
        for(int j=0; j<N; j++){
            scanf("%d", &matrixA[i][j]);
        }
    }

    // 输入矩阵B
    for(int i=0; i<N; i++){
        for(int j=0; j<K; j++){
            scanf("%d", &matrixB[i][j]);
        }
    }

    multiply(M, N, K, matrixA, matrixB, matrixC);
    
    // 输出结果
    for(int i=0; i<M; i++){
        for(int j=0; j<K; j++){
            printf("%d ", matrixC[i][j]);
        }
        printf("\n");
    }
    
    // 释放内存,避免泄漏
    for(int i=0; i<M; i++) free(matrixA[i]);
    free(matrixA);
    for(int i=0; i<N; i++) free(matrixB[i]);
    free(matrixB);
    for(int i=0; i<M; i++) free(matrixC[i]);
    free(matrixC);
    
    return 0;
}

关键知识点总结

  • 栈上的二维数组(包括VLA)和动态分配的int**二维数组是完全不同的内存结构,不能强制转换混用。
  • 矩阵乘法的三重循环索引顺序要对应:C[i][j]是A的第i行和B的第j列对应元素相乘求和。

内容的提问来源于stack exchange,提问作者ArasChang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 19:20:32