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

使用char**存储地图触发段错误,请求代码问题排查

段错误问题分析与修复

问题背景

需要编写函数遍历存储在char **中的地图,检查每个字符周围8个位置(共9个)中至少有2个'#',使用matrix_t结构体实现检查逻辑。仅允许使用指定函数/系统调用,但程序出现段错误,Valgrind显示错误触发在set_mat_nbr的if语句中。

相关代码如下:

create_matrix函数

matrix_t *create_matrix(char **map, size_t y, size_t x)
{
    matrix_t *out = malloc(sizeof(matrix_t));
    if (!out) {
        my_perr("[ERROR] Memory's allocation failure\n");
    }
    out->nbr = 0;
    set_mat_nbr(out, map, y - 1, x);
    set_mat_nbr(out, map, y, x);
    set_mat_nbr(out, map, y + 1, x);
    return out;
}

set_mat_nbr函数

void set_mat_nbr(matrix_t *matrix, char **map, long y, long x)
{
    if (y != 0 && map[y] != NULL && x != 0 && map[y][x - 1] == '#') {
        matrix->nbr++;
    }
    if (y != 0 && map[y] != NULL && map[y][x] == '#') {
        matrix->nbr++;
    }
    if (y != 0 && map[y] != NULL && map[y][x + 1] == '#') {
        matrix->nbr++;
    }
}

调用函数check_border

void check_border(char **map)
{
    size_t y = 0, x = 0;
    matrix_t *matrix = NULL;
    while (map[0][x] != '\0') {
        matrix = create_matrix(map, 0, x);
        if (matrix->nbr < 2) {
            my_perr("[ERROR] Corrupted border\n");
        }
        free(matrix);
        x++;
    }
}

问题分析与修复

1. 无符号整数溢出导致非法索引

create_matrix的y参数是size_t(无符号整数),当调用create_matrix(map, 0, x)时,y - 1会因无符号溢出变成极大值(如SIZE_MAX),访问map[y-1]必然越界触发段错误。

修复:
添加边界判断避免溢出,同时确认y+1对应的行存在:

matrix_t *create_matrix(char **map, size_t y, size_t x)
{
    matrix_t *out = malloc(sizeof(matrix_t));
    if (!out) {
        my_perr("[ERROR] Memory's allocation failure\n");
        exit(EXIT_FAILURE); // 内存分配失败后终止程序,避免空指针访问
    }
    out->nbr = 0;
    // 仅当y>0时处理y-1行
    if (y > 0) {
        set_mat_nbr(out, map, (long)y - 1, x);
    }
    set_mat_nbr(out, map, (long)y, x);
    // 确认y+1行存在再处理
    if (map[y+1] != NULL) {
        set_mat_nbr(out, map, (long)y + 1, x);
    }
    return out;
}

2. set_mat_nbr边界检查逻辑错误

  • 多余的y != 0判断:导致y=0的行完全不被处理,与检查顶部边界的需求矛盾。
  • 缺少x+1越界检查:访问map[y][x+1]时未确认是否超出字符串长度,可能访问非法内存。
  • 检查顺序虽无错误,但逻辑覆盖不全。

修复:
移除不必要的判断,补充x方向的边界检查:

void set_mat_nbr(matrix_t *matrix, char **map, long y, size_t x)
{
    if (map[y] == NULL) {
        return;
    }
    // 检查x-1:仅x>0时访问
    if (x > 0 && map[y][x - 1] == '#') {
        matrix->nbr++;
    }
    // 检查当前x位置
    if (map[y][x] == '#') {
        matrix->nbr++;
    }
    // 检查x+1:确认未到字符串末尾
    if (map[y][x + 1] != '\0' && map[y][x + 1] == '#') {
        matrix->nbr++;
    }
}

3. 内存分配失败后未终止程序

create_matrix中malloc失败时仅打印错误,后续访问out->nbr会因空指针触发段错误。

修复:
在malloc失败后调用exit(EXIT_FAILURE)终止程序,如上述修复代码所示。

4. check_border未确认map合法性

若map为空指针或map[0]为NULL,map[0][x]会直接触发段错误。

修复:
添加初始合法性检查:

void check_border(char **map)
{
    if (map == NULL || map[0] == NULL) {
        my_perr("[ERROR] Invalid map\n");
        return;
    }
    size_t y = 0, x = 0;
    matrix_t *matrix = NULL;
    while (map[0][x] != '\0') {
        matrix = create_matrix(map, 0, x);
        if (matrix->nbr < 2) {
            my_perr("[ERROR] Corrupted border\n");
        }
        free(matrix);
        x++;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:50:19