You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

指针未指向矩阵正确地址的原因排查(附递归路径计数代码)

矩阵路径计数问题中指针地址错误的原因分析与修正

问题背景

在解决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;
}

关键修正说明

  1. 调整判断顺序:先检查坐标是否越界,确保指针始终指向矩阵合法区域后,再判断是否为障碍。
  2. 修复终点判断:将||改为&&,只有同时到达右上角才计数。
  3. 简化指针操作:去掉递归中冗余的指针取地址和解引用操作,代码更清晰。

内容的提问来源于stack exchange,提问作者NatsumiStar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:27:05