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

2D游戏中复制地图指针用于洪水填充时的段错误排查问询

2D游戏路径验证问题的修复方案

核心错误定位

段错误的直接原因是两个关键问题:

  1. map_copy内存分配不足:valid_path中ft_calloc(1, sizeof(map->map))仅分配了单个指针的内存,但需要容纳map->h行字符串指针,应该按地图高度分配数组空间。
  2. copy_map逻辑完全倒置:函数原本应该从原地图origin复制到目标copy,但代码里循环条件依赖未初始化的copy,且赋值方向反了,导致复制完全没执行。

分步修复代码

1. 修正copy_map函数

void    copy_map(char **origin, char **copy, int height)
{
    int i;

    i = 0;
    // 按地图高度逐行复制,避免依赖NULL终止符
    while (i < height)
    {
        copy[i] = ft_strdup(origin[i]);
        i++;
    }
    copy[i] = NULL;
}

2. 修复valid_path的内存分配与逻辑

int valid_path(t_map *map)
{
    int y;
    int x;
    int i;

    // 分配足够容纳所有行指针的内存
    map->map_copy = ft_calloc(map->h + 1, sizeof(char *));
    if (!map->map_copy)
        closeprogram("Memory allocation failed\n");
    
    y = map->playery;
    x = map->playerx;
    // 传入地图高度确保完整复制
    copy_map(map->map, map->map_copy, map->h);
    
    // 重置计数,避免多次调用时累计错误
    map->copy_ccount = 0;
    map->copy_ecount = 0;
    
    flood_fill(map, 'P', y, x);
    
    if (map->ccount != map->copy_ccount)
        closeprogram("Map cannot be solved: unreachable collectibles\n");
    if (map->ecount != map->copy_ecount)
        closeprogram("Map cannot be solved: unreachable exit\n");
    
    // 释放复制的地图,避免内存泄漏
    i = 0;
    while (map->map_copy[i])
    {
        free(map->map_copy[i]);
        i++;
    }
    free(map->map_copy);
    return (1);
}

3. 给flood_fill添加边界检查

当前函数没有判断坐标是否超出地图范围,会导致越界访问,必须加上边界判断:

static void flood_fill(t_map *map, int paint, int y, int x)
{
    // 坐标合法性检查:不能超出地图边界
    if (y < 0 || y >= map->h || x < 0 || x >= map->w)
        return;
    // 遇到墙体直接返回
    if (map->map_copy[y][x] == '1')
        return;
    
    if (map->map_copy[y][x] == 'C')
    {
        map->copy_ccount++;
        map->map_copy[y][x] = '0';
    }
    else if (map->map_copy[y][x] == 'E')
    {
        map->copy_ecount++;
        map->map_copy[y][x] = '0';
    }
    
    if (map->map_copy[y][x] == '0')
    {
        map->map_copy[y][x] = paint;
        flood_fill(map, paint, y, x + 1);
        flood_fill(map, paint, y, x - 1);
        flood_fill(map, paint, y + 1, x);
        flood_fill(map, paint, y - 1, x);
    }
}

4. 修复read_map的宽度计算逻辑

原代码的宽度计算会导致无限循环,修正如下:

t_map   *read_map(char *argv )
{
    t_map   *new;
    int     y;

    new = (t_map *) ft_calloc(1, sizeof(t_map));
    new->fd = open(argv, O_RDONLY);
    new->h = 0;
    new->w = 0;
    y = 0;
    if (new->fd < 0)
    {
        ft_putstr("Map file does not exist\n");
        exit (1);
    }
    while (get_next_line(new->fd))
        new->h += 1;
    close (new->fd);
    new->map = (char **) ft_calloc(new->h + 1, sizeof(char *));
    new->fd = open(argv, O_RDONLY);
    while (y < new->h)
    {
        new->map[y] = get_next_line(new->fd);
        y++;
    }
    // 正确计算地图宽度(假设所有行长度一致)
    while (new->map[0][new->w] != '\0')
        new->w++;
    close(new->fd);
    return (new);
}

关于你的疑问

不需要重新打开地图文件复制内容。原地图已经加载到map->map中,直接复制这个二维数组是最高效的方式,重新读文件只会增加IO开销,还可能引入新的错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:05:25