指针未指向矩阵正确地址的原因排查(附递归路径计数代码)
矩阵路径计数问题中指针地址错误的原因分析与修正
问题背景
在解决JudgeGirl平台的矩阵路径计数问题时,代码中的指针未指向矩阵正确地址,导致逻辑出错。
题目要求
编写程序计算从矩阵左下角到右上角的路径数量:
- 矩阵r行c列,仅可向右或向上移动一格
- 0表示障碍,1表示可通行,起点(左下角)和终点(右上角)均为可通行状态
- 建议用递归实现
限制条件
- r和c均不超过12
输入格式
- 第一行输入r和c
- 后续r行输入矩阵状态
错误代码
#include <stdio.h> #include <assert.h> void count(int x, int y, int r, int c, int *ptr, int *ways){ if((*ptr==0)||(x>(c-1))||(y<0)){ return; }else{ //printf("(%d, %d) %d", x, y, *matrix); } if((x==(c-1))||(y==0)){ *ways += 1; return; } count(x+1, y, r, c, &(*(ptr+1)), &(*ways)); count(x, y-1, r, c, &(*(ptr-c)), &(*ways)); return; } int main(){ int r, c; //y:r x:c scanf("%d %d", &r, &c); assert((r<=12)&&(c<=12)); int matrix[c][r]; for(int j=0; j<r; j++){ for(int i=0; i<c; i++){ scanf("%d", &matrix[i][j]); //printf("%d ", matrix[i][j]); } //printf("\n"); } int ways = 0; count(0, r-1, r, c, &matrix[0][r-1], &ways); //from(0,r-1) to (c-1,0) printf("%d", ways); return 0; }
指针地址错误的核心原因
1. 边界判断顺序错误导致非法内存访问
代码中先判断*ptr==0,再检查x、y是否越界。当x超过c-1或y小于0时,ptr已经指向矩阵外部的非法内存,此时解引用*ptr会触发未定义行为,表现为指针地址指向错误区域。
2. 递归调用中指针传递的冗余写法(非致命但易混淆)
递归时使用&(*(ptr+1))和&(*ways)属于多余操作:
&(*ptr)等价于ptr,直接写ptr+1即可ways本身就是指针,无需再取地址
附加逻辑错误(影响计数结果)
终点判断用了||而非&&,导致只要x到达最右列或y到达最上行就计数,而非同时到达右上角,这会造成路径计数虚高。
修正后的代码
#include <stdio.h> #include <assert.h> void count(int x, int y, int r, int c, int *ptr, int *ways) { // 先判边界,避免非法指针访问 if (x > c-1 || y < 0) { return; } // 再判当前位置是否为障碍 if (*ptr == 0) { return; } // 同时到达右上角才计数 if (x == c-1 && y == 0) { *ways += 1; return; } // 向右移动:指针直接+1 count(x+1, y, r, c, ptr+1, ways); // 向上移动:指针减c(每行有c个元素) count(x, y-1, r, c, ptr - c, ways); } int main() { int r, c; scanf("%d %d", &r, &c); assert(r <= 12 && c <= 12); int matrix[c][r]; for (int j = 0; j < r; j++) { for (int i = 0; i < c; i++) { scanf("%d", &matrix[i][j]); } } int ways = 0; count(0, r-1, r, c, &matrix[0][r-1], &ways); printf("%d", ways); return 0; }
关键修正说明
- 调整判断顺序:先检查坐标是否越界,确保指针始终指向矩阵合法区域后,再判断是否为障碍。
- 修复终点判断:将
||改为&&,只有同时到达右上角才计数。 - 简化指针操作:去掉递归中冗余的指针取地址和解引用操作,代码更清晰。
内容的提问来源于stack exchange,提问作者NatsumiStar
相关产品推荐
相关产品推荐

