二维数组传入函数后取值异常,主对角线校验功能故障求助
问题排查:二维数组传参后元素取值异常
我尝试实现一个功能:从文本文件读取矩阵(首行是矩阵大小,后续行是矩阵元素),将二维数组传入checkDiag函数,校验主对角线元素是否全部相同(相同返回1,否则返回0)。但发现主函数中数组定义正确,打印数组索引值正常,传入函数后第一行取值正确,其他行出现异常值(如matrix[1][1]在函数中输出0,主函数中输出正确值4),请求排查问题原因。
代码示例
#include <stdio.h> int checkDiag(int matrix[][100], int size){ int checkTrue = 0; for (int k = 0; k < size-1; ++k) { if(matrix[k][k] == matrix[k+1][k+1] ){ checkTrue = 1; } else{ checkTrue = 0; } } printf("index 1 1 (funct): %d\n", matrix[1][1]); return checkTrue; } int main(){ FILE *fp; fp = fopen("matrix1.txt", "r"); int size; fscanf(fp, "%d", &size); int matrix[size][size]; int i, j; for (i=0; i<size; ++i) for (j=0; j<size; ++j) fscanf (fp, "%d", &matrix[i][j]); printf("index 1 1 (main): %d\n", matrix[1][1]); int result = checkDiag(matrix, size); printf("%d\n", result); fclose(fp); return 0; }
文本文件内容
3 4 5 6 7 4 9 3 6 4
问题根源
函数参数声明的int matrix[][100]和主函数中定义的变长数组int matrix[size][size]内存布局不匹配。
C语言中二维数组按行优先连续存储:
- 主函数里的数组是
size×size结构,比如size=3时,每行仅3个元素; - 但函数里强制把数组解析为每行100个元素的结构,导致内存偏移计算错误。
比如主函数中matrix[1][1]的实际内存偏移是1*3 +1=4个int的位置,但函数里会计算成1*100 +1=101个int的位置,直接访问了错误的内存区域,所以拿到异常值。
解决方法
方法1:使用变长数组作为函数参数(推荐)
让函数参数和主函数的数组结构匹配,编译器就能正确计算内存偏移,注意要把size参数放在数组参数前面:
int checkDiag(int size, int matrix[size][size]){ int checkTrue = 1; for (int k = 0; k < size-1; ++k) { if(matrix[k][k] != matrix[k+1][k+1] ){ checkTrue = 0; break; // 发现不同直接退出,提升效率 } } printf("index 1 1 (funct): %d\n", matrix[1][1]); return checkTrue; }
方法2:用一维数组模拟二维数组传递(兼容老编译器)
如果编译器不支持C99变长数组,可以把二维数组当成一维数组传递,手动计算索引:
int checkDiag(int *matrix, int size){ int checkTrue = 1; for (int k = 0; k < size-1; ++k) { if(matrix[k*size +k] != matrix[(k+1)*size + (k+1)] ){ checkTrue = 0; break; } } printf("index 1 1 (funct): %d\n", matrix[1*size +1]); return checkTrue; }
调用时传递数组首地址:
int result = checkDiag(&matrix[0][0], size);
额外优化
原checkDiag函数逻辑有漏洞:如果前面元素不相等,后面的相等会把checkTrue重置为1,导致结果错误。建议初始设为1,一旦发现不相等就置0并跳出循环,既准确又高效。
内容的提问来源于stack exchange,提问作者warherolion
相关产品推荐
相关产品推荐

