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

C语言普通矩阵转稀疏矩阵代码运行异常问题排查

问题排查与修复方案

核心错误点

    1. 二维指针传值导致内存分配失效
      C语言函数参数为值传递,你在newMatrix、moveToSparse内部对matrix、sparseMat的malloc赋值仅修改了函数栈上的形参副本,主函数中的mat1、sparseMat1等全局指针仍然为NULL,访问matrix[i][j]自然触发内存越界异常。
    1. 稀疏矩阵内存分配不足
      你仅为sparseMat的前3个行指针分配了内存,当原矩阵非0元素数量超过2时,访问sparseMat[k]会操作野指针,直接崩溃。需要先统计原矩阵非0元素总数,再按实际需求分配稀疏矩阵的行空间。
    1. 稀疏矩阵头字段存储错误
      稀疏矩阵第一行第三列应存储非0元素的总个数,你当前逻辑中k的最终值为「非0元素个数+1」,直接赋值会导致头数据错误。
    1. 补充问题:随机数未初始化种子
      未调用srand初始化随机种子,每次运行生成的矩阵都是固定值,需要引入time.h后在main开头添加随机种子初始化逻辑。
    1. 补充问题:全局循环变量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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:09:04