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

作为人工智能课程的一部分,我正在研究一个游戏解决机器人(滚动石头),我是在这里找到的。这个代码是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;        /* 测试目标是否在模式中,如果是,则没有死锁,或者         * 测试镜像模式,看看是否发现死锁 */        /* 首先检查模式溢出 */        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是空的,所以我们得到了分段错误。 这是相关代码

我已经将代码移植到GitHub。你可以在这里查看 这里

注意:我还尝试在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()循环处理)。

如果这表明了代码其余部分的可移植性,那么我认为将它移植到你当前的机器上可能是一个相当大的项目。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注