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

动态分配二维数组时出现内存访问违规问题求助

解决动态二维数组赋值时的内存访问违规问题

问题分析

你的代码里有几个关键问题会导致内存访问违规或输入异常:

  • scanf格式字符串错误:scanf("%d\n", &maze[i][j])里的\n完全多余。scanf的格式字符串中,空白字符(包括换行、空格)会让它跳过所有连续空白,直到读取到非空白字符。这会导致输入到最后一列时,程序一直等待额外输入,甚至在输入结束时触发未定义行为。
  • 未检查内存分配结果:malloc可能因内存不足返回NULL,如果直接访问maze[i]或maze[i][j],会直接触发内存访问违规。
  • 输入范围逻辑冗余:原本的条件判断可以简化,只对需要输入的区域(i从1到m,j从1到n)进行读取,避免多余的判断。

修正后的代码

#include <stdio.h>
#include <stdlib.h>

int main() {
    int m, n;
    // 检查输入是否有效
    if (scanf("%d%d", &m, &n) != 2) {
        printf("输入错误\n");
        return 1;
    }

    // 分配行指针数组,检查分配是否成功
    int** maze = malloc(sizeof(int*) * (m + 2));
    if (maze == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    // 分配每一行的内存,检查分配是否成功,失败则释放已分配内存
    for (int i = 0; i < m + 2; i++) {
        maze[i] = malloc(sizeof(int) * (n + 2));
        if (maze[i] == NULL) {
            printf("内存分配失败\n");
            for (int k = 0; k < i; k++) {
                free(maze[k]);
            }
            free(maze);
            return 1;
        }
    }

    // 初始化上下左右边界为1
    for (int i = 0; i < m + 2; i++) {
        maze[i][0] = 1;
        maze[i][n + 1] = 1;
    }
    for (int j = 0; j < n + 2; j++) {
        maze[0][j] = 1;
        maze[m + 1][j] = 1;
    }

    // 读取中间区域的输入值
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (scanf("%d", &maze[i][j]) != 1) {
                printf("输入错误\n");
                // 清理已分配内存
                for (int k = 0; k < m + 2; k++) {
                    free(maze[k]);
                }
                free(maze);
                return 1;
            }
        }
    }

    // 打印最终的二维数组
    for (int i = 0; i < m + 2; i++) {
        for (int j = 0; j < n + 2; j++) {
            if (j == n + 1) {
                printf("%d\n", maze[i][j]);
            } else {
                printf("%d ", maze[i][j]);
            }
        }
    }

    // 释放所有动态分配的内存
    for (int i = 0; i < m + 2; i++) {
        free(maze[i]);
    }
    free(maze);

    return 0;
}

关键修改说明

  1. 移除scanf中的\n:统一使用scanf("%d", &maze[i][j]),保证输入流程正常执行。
  2. 添加内存分配检查:每次调用malloc后都判断是否返回NULL,避免访问空指针;分配失败时会释放已分配的内存,防止内存泄漏。
  3. 优化边界初始化:单独初始化四个边界,比嵌套循环的条件判断更清晰高效。
  4. 限制输入范围:仅对需要输入的区域读取数据,减少不必要的条件判断逻辑。
  5. 添加输入有效性检查:通过scanf的返回值判断输入是否为有效整数,避免非法输入导致程序异常。
  6. 添加内存释放步骤:程序结束前释放所有动态分配的内存,杜绝内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:34:55