C语言普通矩阵转稀疏矩阵代码运行异常问题排查
问题排查与修复方案
核心错误点
- 二维指针传值导致内存分配失效
C语言函数参数为值传递,你在newMatrix、moveToSparse内部对matrix、sparseMat的malloc赋值仅修改了函数栈上的形参副本,主函数中的mat1、sparseMat1等全局指针仍然为NULL,访问matrix[i][j]自然触发内存越界异常。
- 二维指针传值导致内存分配失效
- 稀疏矩阵内存分配不足
你仅为sparseMat的前3个行指针分配了内存,当原矩阵非0元素数量超过2时,访问sparseMat[k]会操作野指针,直接崩溃。需要先统计原矩阵非0元素总数,再按实际需求分配稀疏矩阵的行空间。
- 稀疏矩阵内存分配不足
- 稀疏矩阵头字段存储错误
稀疏矩阵第一行第三列应存储非0元素的总个数,你当前逻辑中k的最终值为「非0元素个数+1」,直接赋值会导致头数据错误。
- 稀疏矩阵头字段存储错误
- 补充问题:随机数未初始化种子
未调用srand初始化随机种子,每次运行生成的矩阵都是固定值,需要引入time.h后在main开头添加随机种子初始化逻辑。
- 补充问题:随机数未初始化种子
- 补充问题:全局循环变量i,j存在逻辑冲突风险,建议改为函数内局部变量。
修复后代码示例
#include <stdio.h> #include <stdlib.h> #include <time.h> // 函数改为返回分配好的二维指针,避免三级指针传参的复杂度 int** newMatrix(int n) { int i,j; // 先分配行指针数组 int** matrix = (int**)malloc(n * sizeof(int*)); for (i = 0; i < n; i++) { matrix[i] = (int*)malloc(sizeof(int) * n); } // 随机赋值,刻意提高0的比例符合稀疏矩阵特征,可自行修改 for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { matrix[i][j] = rand() % 5 == 0 ? rand()%100 : 0; } } return matrix; } int** moveToSparse(int** matrix, int n) { int i,j,k = 1; // 第一步:先统计非0元素总数 int non_zero_cnt = 0; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (matrix[i][j] > 0) non_zero_cnt++; } } // 第二步:按非0数+1(头行)的数量分配稀疏矩阵空间 int** sparseMat = (int**)malloc((non_zero_cnt + 1) * sizeof(int*)); for (i = 0; i <= non_zero_cnt; i++) { sparseMat[i] = (int*)malloc(3 * sizeof(int)); } // 填充头行:行数、列数、非0元素数 sparseMat[0][0] = n; sparseMat[0][1] = n; sparseMat[0][2] = non_zero_cnt; // 填充非0元素 for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (matrix[i][j]>0) { sparseMat[k][0] = i; sparseMat[k][1] = j; sparseMat[k][2] = matrix[i][j]; k++; } } } return sparseMat; } // 测试用打印函数 void printSparse(int** sparseMat) { int cnt = sparseMat[0][2]; printf("稀疏矩阵头:行数=%d, 列数=%d, 非0元素数=%d\n", sparseMat[0][0], sparseMat[0][1], cnt); for (int i = 1; i <= cnt; i++) { printf("位置(%d,%d) 值=%d\n", sparseMat[i][0], sparseMat[i][1], sparseMat[i][2]); } } int main(void){ // 初始化随机种子 srand((unsigned int)time(NULL)); int size1 = rand() % 10 + 10; int size2 = rand() % 10 + 10; // 接收函数返回的分配好的矩阵指针 int **mat1 = newMatrix(size1); int **mat2 = newMatrix(size2); int **sparseMat1 = moveToSparse(mat1, size1); int **sparseMat2 = moveToSparse(mat2, size2); // 测试打印 printSparse(sparseMat1); // 用完记得补充释放内存逻辑,避免内存泄漏 return 0; }
内容的提问来源于stack exchange,提问作者emptyinteger
相关产品推荐
相关产品推荐

