打印矩阵时出现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
相关产品推荐
相关产品推荐

