Gauss-Jacobi迭代法求解Ax=B的C代码运行异常问题排查
Gauss-Jacobi迭代法C程序故障排查
直接导致运行异常的错误点
- 关键字冲突
你使用bool作为普通整型变量名,bool是C标准规定的布尔类型关键字,需要引入<stdbool.h>才能使用,未引入对应头文件时会直接触发编译报错,即使编译通过也存在类型冲突隐患。 - 维度变量逻辑混乱
Gauss-Jacobi迭代求解的线性方程组Ax=B中系数矩阵A必须为n阶方阵,x、B均为n维向量,你额外定义了m变量控制列数完全没有必要。且你注释的输入代码存在笔误:printf("m=") ; scanf("%d", &n),如果放开注释会导致输入的m值直接覆盖n,维度逻辑完全混乱。 - 对角线合法性检查时机错误
你在输入a[i][j]的内层循环中判断a[i][i]是否趋近于0,但当j还未遍历到i时,a[i][i]是未初始化的垃圾值,该判断完全无效,可能触发程序无理由提前退出。 - 无收敛校验与迭代上限
Gauss-Jacobi迭代仅当系数矩阵满足严格对角占优或不可约对角占优时才会收敛,你未提前做收敛性校验,也没有设置最大迭代次数上限,输入不满足收敛条件的矩阵时会直接进入无限循环,看起来就是程序卡住无法运行。 - 内存分配未做校验
你调用malloc后没有检查返回值是否为NULL,一旦内存分配失败,后续对指针的读写操作会直接触发段错误崩溃。
核心修复示例
#include <math.h> #include <stdlib.h> #include <stdio.h> int main(void) { double **a, *b, *x, *f, eps = 1.e-2, c; // 移除冗余m变量,修改bool变量名为iter_flag,增加最大迭代次数限制 int n = 3, i, j, iter_flag = 1, max_iter = 1000, iter_cnt = 0; /* 修复输入笔误 printf("n=") ; scanf("%d", &n); */ a = malloc(n * sizeof *a); if (a == NULL) { printf("内存分配失败\n"); return 1; } for (i = 0; i < n; i++) { a[i] = malloc(n * sizeof(double)); if (a[i] == NULL) { printf("内存分配失败\n"); return 1; } } b = malloc(n * sizeof *b); x = malloc(n * sizeof *x) ; f = malloc(n * sizeof *f) ; if (b == NULL || x == NULL || f == NULL) { printf("内存分配失败\n"); return 1; } // 输入系数矩阵 for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { printf("a[%d][%d]=", i, j); scanf("%le", &a[i][j]); } printf("\n") ; } // 移到矩阵输入完成后判断对角线合法性 for (i = 0; i < n; i++) { if(fabs(a[i][i])<1.e-10) { printf("系数矩阵对角线存在零元素,无法迭代\n"); return 0; } } // 打印系数矩阵 printf("输入的系数矩阵A:\n"); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { printf("%le ", a[i][j]); } printf("\n") ; } // 输入初始迭代值 printf("输入初始迭代值x:\n"); for (j = 0; j < n; j++) { printf("x[%d]=", j); scanf("%le", &x[j]); } printf("\n") ; // 输入常数项b printf("输入常数项b:\n"); for (j = 0; j < n; j++) { printf("b[%d]=", j); scanf("%le", &b[j]); } printf("\n") ; // 迭代逻辑增加次数限制 while (iter_flag && iter_cnt < max_iter) { iter_cnt++; iter_flag = 0; for (i = 0; i < n; i++) { c = 0.0; for (j = 0; j < n; j++) if (j != i) c += a[i][j] * x[j]; f[i] = (b[i] - c) / a[i][i]; } for (i = 0; i < n; i++) if (fabs(f[i] - x[i]) > eps) iter_flag = 1; if (iter_flag == 1) for (i = 0; i < n; i++) x[i] = f[i]; else break; } if (iter_cnt >= max_iter) { printf("达到最大迭代次数,迭代可能不收敛,当前计算结果为:\n"); } else { printf("迭代收敛,结果为:\n"); } for (j = 0; j < n; j++) printf("x[%d] = %le\n", j, f[j]); // 释放内存避免泄漏 for (i = 0; i < n; i++) { free(a[i]); } free(a); free(b); free(x); free(f); return 0; }
内容的提问来源于stack exchange,提问作者Nickie
相关产品推荐
相关产品推荐

