C语言基于多维数组与循环的矩阵乘法程序输出异常(疑似地址)求排查
问题定位与代码修正
你的程序输出随机乱码/疑似内存地址值的核心原因是数组索引规则不统一、循环边界与矩阵维度错配、结果赋值位置错位,触发了C语言栈内存的未定义访问,具体问题点如下:
- 索引起始逻辑冲突:C语言多维数组默认从
0开始索引合法空间,但你在输入矩阵、打印结果时使用1起始的循环范围,实际乘法计算环节又切回0起始范围,直接读取了未初始化的栈内存当作矩阵元素参与运算 - 矩阵输入的遍历维度完全错配:
- 矩阵A(
r1行c1列)的输入循环中,列遍历上限写为c2,未按实际c1列的长度输入元素 - 矩阵B(
r2行c2列)的输入循环中,行遍历上限写为r1,未按实际r2行的长度输入元素
- 矩阵A(
- 结果赋值位置错位:
result[i][j] = sum的代码写在了列循环的外侧,列循环结束时j的值等于c2(超出数组合法索引范围),相当于所有合法位置的result元素完全没有被赋值,全为栈随机值 - 越界访问风险:1起始的循环索引会访问到数组下标为10的位置,超出
a[10][10]、b[10][10]、result[10][10]的合法范围(合法下标为0~9),触发未定义行为
修正后可运行代码
#include <stdio.h> int main() { int a[10][10], b[10][10], result[10][10]; int r1, c1, r2, c2, i, j, k; printf("请输入矩阵A的行数和列数:"); scanf("%d %d", &r1, &c1); printf("请输入矩阵B的行数和列数:"); scanf("%d %d", &r2, &c2); // 校验矩阵乘法的维度匹配要求:A的列数 = B的行数 while (c1 != r2) { printf("维度不满足乘法要求,请重新输入:\n"); printf("请输入矩阵A的行数和列数:"); scanf("%d %d", &r1, &c1); printf("请输入矩阵B的行数和列数:"); scanf("%d %d", &r2, &c2); } // 输入矩阵A元素:r1行c1列,统一0索引 printf("请输入矩阵A的元素:\n"); for (i = 0; i < r1; i++) { for (j = 0; j < c1; j++) { scanf("%d", &a[i][j]); } } // 输入矩阵B元素:r2行c2列,统一0索引 printf("请输入矩阵B的元素:\n"); for (i = 0; i < r2; i++) { for (j = 0; j < c2; j++) { scanf("%d", &b[i][j]); } } // 矩阵乘法计算,每个结果元素单独初始化后累加 for (i = 0; i < r1; i++) { for (j = 0; j < c2; j++) { result[i][j] = 0; for (k = 0; k < c1; k++) { result[i][j] += a[i][k] * b[k][j]; } } } // 打印结果,和计算时的索引范围保持一致 printf("矩阵乘法结果:\n"); for (i = 0; i < r1; i++) { for (j = 0; j < c2; j++) { printf("%d\t", result[i][j]); } printf("\n"); } return 0; }
修正核心逻辑
- 全流程统一使用0作为数组起始索引,避免索引错位
- 输入环节严格匹配每个矩阵的实际行列维度,不混同其他矩阵的维度参数
- 结果赋值直接在三层乘法循环内部完成,每计算完一个位置的累加和就对应赋值,不再依赖全局累加变量
- 打印环节和计算环节使用完全一致的索引范围,不会读取越界的随机内存值
内容的提问来源于stack exchange,提问作者dark
相关产品推荐
相关产品推荐

