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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在运行非常旧的C代码时遇到分段错误相关的知识,希望对你有一定的参考价值。

作为人工智能课程的一部分,我正在研究游戏解决机器人(滚石)我找到了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);

但是,Array是空的,因此我们得到了分段错误。 Here are the code in question

我已将代码移植到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]的typedef。快速浏览一下DL.1表明它似乎是大端32位整数。如果你在x86上运行它,那么你的int是32位小端。因此,您需要在读取数据后对其进行字节交换(例如,通过使用ntohl()循环它)。

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

以上是关于在运行非常旧的C代码时遇到分段错误的主要内容,如果未能解决你的问题,请参考以下文章

用于在C中为二叉搜索树分配内存的分段错误

来自 for 循环的分段错误

C ++ std :: list分段错误[重复]

在Linux机器上运行C代码时出现分段错误(核心转储)[关闭]

非常简单的分段错误错误c ++ [关闭]

在使用 Qt 创建者创建一个非常简单的项目时遇到 Qt 中的“分段错误”