C语言中矩阵二次打印结果异常的原因排查求助
问题分析与解决方案:矩阵二次打印值异常
嘿,这个问题的根源其实是代码里一个非常隐蔽但致命的错误——数组声明时使用了未初始化的变量,导致内存越界访问,最终出现了诡异的打印结果。
让我拆解一下问题:
- 你看代码开头的声明:
int i,j,n,matrica[i][j],suma=0;这里的i和j都是未初始化的局部变量,它们的值是栈上的随机垃圾值。用这俩变量来定义二维数组matrica的大小,意味着数组的实际尺寸完全不是你后续要用的n×n。 - 当你第一次循环给
matrica[i][j]赋值时,你其实是在往栈上不属于这个数组的内存区域写数据。这些区域可能刚好覆盖了循环变量i、j或者其他栈上变量的存储位置。第一次打印时数据刚写入还没被破坏,所以看起来正常;但循环结束后栈内存已经被篡改,第二次遍历访问时,就读到了被越界写入修改后的数据,也就出现了你看到的从左下角到右上角复制的奇怪规律。
修正方案
核心就是先获取n的值,再用已初始化的n来声明数组,避免使用未初始化变量定义数组大小:
修正后的完整代码(支持C90及以上的变长数组)
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int i, j, n, suma = 0; srand(time(NULL)); printf("\nunesi prirodan broj N[3,20] = \n"); scanf("%d", &n); // 必须在n被赋值后,再声明n×n的二维数组 int matrica[n][n]; // 第一次赋值并打印 for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { matrica[i][j] = rand() % 100; printf("%d, %d = %4d ", i, j, matrica[i][j]); if(j == n - 1) { printf("\n"); } } } printf("\n"); // 第二次打印 for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { printf("%d, %d = %4d ", i, j, matrica[i][j]); if(j == n - 1) { printf("\n"); } } } return 0; }
如果你用的是不支持变长数组的C89标准
可以用动态内存分配来创建二维数组,这样兼容性更好:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int i, j, n, suma = 0; srand(time(NULL)); printf("\nunesi prirodan broj N[3,20] = \n"); scanf("%d", &n); // 动态分配二维数组 int **matrica = malloc(n * sizeof(int *)); for(i = 0; i < n; i++) { matrica[i] = malloc(n * sizeof(int)); } // 第一次赋值并打印 for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { matrica[i][j] = rand() % 100; printf("%d, %d = %4d ", i, j, matrica[i][j]); if(j == n - 1) { printf("\n"); } } } printf("\n"); // 第二次打印 for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { printf("%d, %d = %4d ", i, j, matrica[i][j]); if(j == n - 1) { printf("\n"); } } } // 记得释放动态分配的内存 for(i = 0; i < n; i++) { free(matrica[i]); } free(matrica); return 0; }
这样修改后,两次打印的结果就会完全一致了,因为数组的大小正确,不会再发生内存越界的问题。
内容的提问来源于stack exchange,提问作者Mario Plantosar
相关产品推荐
相关产品推荐

