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

打印矩阵时出现Segmentation Fault,请求排查代码内存分配问题

问题分析与修复方案

核心错误点

  • make_matrix内存分配逻辑完全错误
    原代码直接用xcalloc(n_rows, sizeof(double*))分配内存并转为Matrix*,但Matrix结构体的内存布局和double*数组完全不匹配,导致rows、cols、data成员的内存混乱。同时data指针未为行指针和每行的列数据分配有效内存,访问mat->data[i][j]必然触发段错误。
  • copy_matrix数组索引计算错误
    原代码用data[i] + j赋值,这是把一维数组第i个元素与j相加,而非取对应矩阵位置的元素。正确索引应为data[i * n_cols + j],因为输入的一维数组是按行优先存储的。
  • 缺失内存释放逻辑
    代码未提供矩阵内存释放函数,长期运行会导致内存泄漏(非段错误直接原因,但属于必要优化)。

修复后的完整代码

#include "base.h"
#include <stdio.h>

struct Matrix {
    int rows; // 行数
    int cols; // 列数
    double** data; // 指向行指针数组的指针,每个行指针指向含cols个double的数组
};
typedef struct Matrix Matrix;

Matrix* make_matrix(int n_rows, int n_cols) {
    // 1. 分配Matrix结构体本身的内存
    Matrix* mat = xcalloc(1, sizeof(Matrix));
    mat->rows = n_rows;
    mat->cols = n_cols;
    
    // 2. 分配行指针数组的内存
    mat->data = xcalloc(n_rows, sizeof(double*));
    
    // 3. 为每一行分配列数据的内存
    for (int i = 0; i < n_rows; i++) {
        mat->data[i] = xcalloc(n_cols, sizeof(double));
    }
    
    return mat;
}

Matrix* copy_matrix(double* data, int n_rows, int n_cols) {
    Matrix* mat = make_matrix(n_rows, n_cols);
    for (int i = 0; i < mat->rows; i++) {
        for (int j = 0; j < mat->cols; j++) {
            // 正确映射一维数组到二维矩阵的索引
            mat->data[i][j] = data[i * n_cols + j];
        }
    }
    return mat;
}

void print_matrix(Matrix* m) {
    for (int i = 0; i < m->rows; i++) {
        for (int j = 0; j < m->cols; j++) {
            printf("%g ", m->data[i][j]);
        }
        // 每行打印完换行,增强可读性
        printf("\n");
    }
}

// 添加内存释放函数,避免内存泄漏
void free_matrix(Matrix* m) {
    if (m == NULL) return;
    for (int i = 0; i < m->rows; i++) {
        xfree(m->data[i]);
    }
    xfree(m->data);
    xfree(m);
}

void matrix_test(void) {
    double a[] = { 
        1, 2, 3, 
        4, 5, 6, 
        7, 8, 9 };
    Matrix* m1 = copy_matrix(a, 3, 3);
    print_matrix(m1);
    free_matrix(m1);

    double a2[] = { 
        1, 2, 3, 
        4, 5, 6 };
    Matrix* m2 = copy_matrix(a2, 2, 3);
    print_matrix(m2);
    free_matrix(m2);

    double a3[] = { 
        1, 2, 
        3, 4, 
        5, 6 };
    Matrix* m3 = copy_matrix(a3, 3, 2);
    print_matrix(m3);
    free_matrix(m3);
}

修复说明

  • make_matrix修正:按“结构体→行指针数组→每行列数据”的顺序分配内存,确保data的每一层指针都指向有效内存区域。
  • 索引计算修正:用i * n_cols + j实现一维数组到二维矩阵的正确映射。
  • 添加free_matrix:逐层释放矩阵内存,避免内存泄漏。
  • print_matrix优化:添加换行操作,让矩阵打印结果更清晰易读。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:20:25