二维矩阵对称性判断程序异常,求排查解决方法
分析你的对称矩阵判断函数问题
首先,先把你的代码贴出来方便讨论:
int IsSym (int ** rels, int universe) { int ii, jj; for ( ii = 1; ii < universe; ii++) { for ( jj = ii; jj < universe; jj++) { if (rels[ii][jj] != rels[jj][ii]) { return 0; } } } return 1; }
这个思路本身是对的——只遍历上三角(含对角线)来检查对称位置元素,效率比遍历整个矩阵高,但它确实存在几个可能导致程序异常的问题:
下标起始值错误:C语言里数组默认是0-based下标,如果你的矩阵是从索引0开始存储的(绝大多数情况都是如此),那你的循环直接跳过了
ii=0的行,也就没检查rels[0][jj]和rels[jj][0](jj从0到universe-1)的对称关系。比如当矩阵第一行和第一列的元素不对称时,你的函数会错误地返回1。二维指针的兼容性问题:如果传入的
rels不是真正的二级指针(比如你用int rels[n][n]这样的栈上二维数组,或者用一维数组模拟二维矩阵时),rels[ii][jj]的内存访问会出问题。因为栈上的二维数组在内存里是连续存储的,它的类型是int (*)[n]而不是int**,强制转换后访问会导致越界或者错误的内存读取。边界条件遗漏:虽然
universe为0或1时函数返回1是合理的,但如果universe和实际矩阵边长不匹配,会直接导致数组越界访问,引发程序崩溃或未知行为。
修正后的代码版本
针对上面的问题,我们可以调整代码如下:
版本1:适配真正的二级指针(动态分配的二维数组)
int IsSym(int **rels, int universe) { if (universe <= 1) { return 1; // 空矩阵或1x1矩阵天然对称 } for (int ii = 0; ii < universe; ii++) { // 从ii开始遍历,避免重复检查对称对 for (int jj = ii; jj < universe; jj++) { if (rels[ii][jj] != rels[jj][ii]) { return 0; } } } return 1; }
版本2:适配连续存储的矩阵(栈上二维数组/一维数组模拟)
如果你的矩阵是用栈上数组或者一维数组模拟的,更推荐这个版本,避免指针类型不匹配问题:
int IsSym(int *rels, int universe) { if (universe <= 1) { return 1; } for (int ii = 0; ii < universe; ii++) { for (int jj = ii; jj < universe; jj++) { // 计算一维数组中的对应索引 if (rels[ii * universe + jj] != rels[jj * universe + ii]) { return 0; } } } return 1; }
额外注意事项
- 确保传入的
universe是矩阵的实际边长,避免出现数组越界访问。 - 如果是动态分配的二维数组,要提前确认每一行都正确分配了内存,不存在空指针的情况。
内容的提问来源于stack exchange,提问作者BunBuns
相关产品推荐
相关产品推荐

