一个关于指针的错误,十分困惑
这是问题函数的代码:
static int m_Simulate(phase& sim_board, int own, POINT last_point) { POINT odds_points[rule::PiecesNums()]; int round = own; while (true) { LINKTYPES lts; sim_board.CheckLinkTypes(round, last_point, lts); if (rule::IsBanMove(last_point, lts)) { if (own == PIECES::WHITE) {return 1;} break; } else if (rule::IsOver(lts)) { if (own == round) {return 1;} break; } round = ~round; int odds_point_nums = ai::GetKeyPoints(sim_board, round, odds_points); if (odds_point_nums < 1) { break; } int odds = randomx::Get(odds_point_nums-1); last_point = odds_points[odds]; // 此处出现段错误信号 sim_board.SetPieces(round, last_point); } return 0; }
问题的症状,就是当这个函数运行了一定次数后,在那一行会出现一个错误,由于是多线程的,而这个函数运行在子线程,出现这个错误后没有任何异样,操作系统也不显示错误报告。只有在调试的时候才能知道出现了一个指针错误。
从调试信息可以看到,odds_points莫名其妙的变成了0xe,这显然是某个地方发生了错误,然后系统或者运行库把这个odds_points改成了0xe。但我真的不明白还有哪里能发生错误。这里唯一将odds_points传出去的,也是传值啊,不是引用啊,不可能会出现这种问题:int GetKeyPoints(phase& board, int own, POINT result[]);
我后来觉得,会不会是POINT odds_points[rule::PiecesNums()];这里的问题,用了自动数组的特性,于是我尝试用另一个模块的走法表来作为odds_points,这个走法表的数组是new的。我试了之后,发现确实这个函数中不会有段错误的提示了。
但是,很奇怪的事出现了,竟然会影响到另一个毫不相干的list:
static UCTNODE* m_SelectPlayNode(list<UCTNODE*>& nodes, int n) { for (auto node : nodes) { if (node->access_nums < 1) // 此处会出现段错误 { return node; } } ...
为什么会段错误?因为node莫名其妙的变成0x0了!而我仔细的调试发现和这个链表相关的那些函数根本没有任何问题,根源依然是那个m_Simulate函数!(在另外一个函数中,是先调用上面的函数,然后再调用m_Simulate,这两个函数没有任何关系,参数也是完全独立的)
因为当我重新恢复POINT odds_points[rule::PiecesNums()];的形式时,上面的函数就不会出现段错误,node也不会莫名其妙的变成0x0。所以我断定这个段错误的根源就是那个m_Simulate引起的。
我怀疑是某个地方莫名其妙的覆盖了别的地方的数据,导致了各种异常表现。这个问题真的很棘手,我在调试时难以获取足够的信息,如果要我看汇编的指令,我也看不出什么来。
真的很困惑很无奈,到底是为什么导致了odds_points会变成0xe,这个肯定也不是根源,应该是更隐蔽的地方导致了这一系列的问题,odds_points用自动数组,在m_Simulate函数里就会出现段错误,莫明其的变成的0xe,不用自动数组,就会影响到另一个毫不相干的list,匪夷所思。这个0xe估计是一个重要的线索,肯定是系统或者运行库检查到某些问题然后改成0xe以提示错误。
说实说我非常想把这个问题归结于编译器和运行库,但我也知道基本不可能的,是我自己某些地方的代码有错误。但这真的很难知道问题到底在哪。
如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

评论(9)




调试时我也想到了,可能还就是int odds_point_nums = ai::GetKeyPoints(sim_board, round, odds_points);的问题,因为以前是用别的函数,在改成用GetKeyPoints函数时问题也就出现了。经过我再三确认,还真的是这里有问题。
但我就完全没有头绪了,因为GetKeyPoints中只是纯粹的写一些数据到result数组中,也没有超出边界的地方。而且最麻烦的是,这个odds_points变成0xe一定会出现,但和运行次数并没有关系,就好像是有一人要跳楼,不知道他会在什么时候跳,但反正他最后一定会跳。
具体是这样的,在另外的一个函数,控制着这个模块的基本流程,循环到指定的次数,每一次都相继调用一些函数,其中就是m_Simulate,而这个odds_points变成0xe的错误,是不定时的,不是固定的每次调用都会出现,也不是固定的某次调用会出现,而是突然在某次调用m_Simulate时的就发生了。所以我感觉很棘手,因为连调试都难。
发布评论
需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。