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

为何矩阵链乘法代码运行时出现Segmentation Fault错误?

修复矩阵链乘法程序的段错误问题

核心问题分析与修复步骤

1. 数组索引越界(最直接的段错误原因)

你的m和s数组使用1-based索引(代码中i从1开始),但分配内存时只申请了n个元素的空间(索引范围0~n-1),当j=i+l-1达到n时,访问m[n][...]会直接越界触发段错误。

修复:
将m和s的内存分配改为n+1个元素,适配1-based索引:

// 调整分配大小为n+1,覆盖1~n的索引
long long **m = (long long **)calloc(n+1, sizeof(long long *));
int **s = (int **)calloc(n+1, sizeof(int *));
// 循环范围改为0到n,初始化所有行
for (int i = 0; i <= n; i++) {
    m[i] = (long long *)calloc(n+1, sizeof(long long));
    s[i] = (int *)calloc(n+1, sizeof(int));
    if (m[i] == NULL || s[i] == NULL) {
        printf("Error: memory allocation failed\n");
        exit(1);
    }
}

2. 维度数组p构造错误

矩阵链乘法的维度数组p应该是n+1个元素:A₁是p[0]×p[1],A₂是p[1]×p[2],…,Aₙ是p[n-1]×p[n]。你当前的代码错误地为每个矩阵单独存储行和列,导致计算q时索引越界。

修复:
重新构造p数组,确保相邻矩阵维度连续:

// main函数中,p的大小改为n+1
int *p = (int *)malloc(sizeof(int) * (n+1));
if (p == NULL) {
    printf("Error: memory allocation failed\n");
    exit(1);
}
srand(time(NULL));
p[0] = rand() % 1001 + 1000; // 第一个矩阵的行数
for (int i = 1; i <= n; i++) {
    // 前一个矩阵的列数 = 当前矩阵的行数,直接继承后生成当前矩阵的列数
    p[i] = rand() % 1001 + 1000;
}

同时修改matrix_chain_multiply中计算q的代码:

long long q = m[i][k] + m[k+1][j] + (long long)p[i-1] * p[k] * p[j];

3. 整数溢出问题

矩阵维度为1000~2000,三个数相乘最大值为2000*2000*2000=8e9,远超过INT_MAX(约2.1e9),会导致整数溢出,引发未定义行为(可能表现为段错误或计算结果异常)。

修复:
将m数组的类型改为long long,避免溢出:

// 替换int为long long存储计算结果
long long **m = (long long **)calloc(n+1, sizeof(long long *));
for (int i = 0; i <= n; i++) {
    m[i] = (long long *)calloc(n+1, sizeof(long long));
}
// 初始化时使用LLONG_MAX替代INT_MAX
m[i][j] = LLONG_MAX;
// 计算q时强制转换为long long避免溢出
long long q = m[i][k] + m[k+1][j] + (long long)p[i-1] * p[k] * p[j];

4. 内存释放的对应调整

因为m和s的大小改为了n+1,释放时也要循环到n:

for (int i = 0; i <= n; i++) {
    free(m[i]);
    free(s[i]);
}
free(m);
free(s);

完整修复后的代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
#include <omp.h>

void matrix_chain_multiply(int *p, int n, int num_threads) {
    // Allocate memory for matrix chain and auxiliary arrays (1-based indexing)
    long long **m = (long long **)calloc(n+1, sizeof(long long *));
    int **s = (int **)calloc(n+1, sizeof(int *));
    if (m == NULL || s == NULL) {
        printf("Error: memory allocation failed\n");
        exit(1);
    }
    for (int i = 0; i <= n; i++) {
        m[i] = (long long *)calloc(n+1, sizeof(long long));
        s[i] = (int *)calloc(n+1, sizeof(int));
        if (m[i] == NULL || s[i] == NULL) {
            printf("Error: memory allocation failed\n");
            exit(1);
        }
    }

    // Set the number of threads
    omp_set_num_threads(num_threads);

    // Compute the matrix chain product using dynamic programming
    for (int l = 2; l <= n; l++) {
        #pragma omp parallel for schedule(dynamic)
        for (int i = 1; i <= n - l + 1; i++) {
            int j = i + l - 1;
            m[i][j] = LLONG_MAX;
            for (int k = i; k <= j - 1; k++) {
                long long q = m[i][k] + m[k+1][j] + (long long)p[i-1] * p[k] * p[j];
                if (q < m[i][j]) {
                    m[i][j] = q;
                    s[i][j] = k;
                }
            }
        }
    }

    // Free memory
    for (int i = 0; i <= n; i++) {
        free(m[i]);
        free(s[i]);
    }
    free(m);
    free(s);
}

int main() {
    int n = 10; // number of matrices
    int num_threads = 4; // number of threads to use
    int *p = (int *)malloc(sizeof(int) * (n+1));
    if (p == NULL) {
        printf("Error: memory allocation failed\n");
        exit(1);
    }
    srand(time(NULL));
    p[0] = rand() % 1001 + 1000; // rows of first matrix
    for (int i = 1; i <= n; i++) {
        p[i] = rand() % 1001 + 1000; // columns of current matrix (rows of next)
    }

    double start_time = omp_get_wtime();
    matrix_chain_multiply(p, n, num_threads);
    double end_time = omp_get_wtime();
    double time = end_time - start_time;
    printf("Time: %f\n", time);

    // Free memory
    free(p);

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 20:57:09