运行 非常旧的 C 代码时遇到分段错误

Encountering Segmentation Faults while running very old C code

作为人工智能课程的一部分,我正在研究一款游戏 解决机器人(滚石)我发现 here。这段代码 写于 1999 年(可能是在 HP UNIX 工作站上)。我似乎无法 运行 在我的平台上(Ubuntu Linux 18.10 x64)。我遇到分段错误 (SIGSEGV、SIGBUS 等)

该代码使用自定义编写的数据结构,如指针使用的位串 算术和引用调用。例如,在一个实例中,我们得到索引 index = t->Array[index][square];

的某种类型的块

我们检查玩家正在移动的可能状态中有哪些是空方块或墙壁。

do {
        p = pos + xofs*t->Sup[i].x_ofs + yofs*t->Sup[i].y_ofs;
        /* test if goal is in the pattern, if yes, no deadlock  or
         * test the mirror pattern to see if that finds a deadlock */

        /* check for pattern overflow first */
        if (p<0 || p>XSIZE*YSIZE) 
            square = WallSquare;
        else {
            if (maze->Phys[p].goal >= 0) {
                goto TEST_MIRROR;
            }
            if (IsBitSetBS(maze->out,p)) square = WallSquare;
            else if (maze->PHYSstone[p]>=0) square = StoneSquare;
            else square = BlancSquare;
        }
        index = t->Array[index][square];
        i++;
       } while (index>0);

但是,数组是 空所以我们得到一个分段错误。 代码如下 问题

我已将代码移植到 GitHub。你可以看看here

注意:我也曾尝试 运行 Ubuntu 16.04.06 X86 和 Visual Studio 2019 中的此代码,但没有成功。

在我的测试中,第一次通过这段代码(当index=0时)我们发现t->Array[0]包含一些巨大的数字。所以 index 被发送到一个巨大的东西,下一次循环,它超过了 t->Array 的大小,你崩溃了。

t->Array 的内容最初从文件 DL.1 中加载到函数 LoadTree:

        t->Next[0] = fread(t->Array,sizeof(DLENTRY),
                t->CurrentLength,fp);

很遗憾,作者选择以他们机器的本机二进制格式存储此数据,这可能与您当前的机器不一致。

现在 DLENTRYint[3] 的类型定义。快速浏览 DL.1 表明它似乎是大端 32 位整数。如果您在 x86 上 运行 this,那么您的 int 是 32 位小端。因此,您需要在读入数据后对其进行字节交换(例如,通过使用 ntohl().)

对其进行循环

如果这是其余代码的可移植性的任何迹象,那么我认为将它移植到您当前的计算机可能是一个重要的项目。