C++ 分割错误?
我目前正在为学校做这个项目,在那里我正在实施一个算法来为“骑士游戏”找到一个解决方案(它是关于找到从棋盘左上角到右下角的最短路径),但我已经三天没有遇到这种分段错误,我检查了我用过的每一个指针,一切似乎都正常。 我实现了“搜索算法”,bfs、dfs和ucs,前两个很好,但ucs给了我分割错误,尽管它们使用的是相同的东西,除了popBest函数。 以下是ucs和popBest功能的一些图片:C++ 分割错误?,c++,c,artificial-intelligence,C++,C,Artificial Intelligence,我目前正在为学校做这个项目,在那里我正在实施一个算法来为“骑士游戏”找到一个解决方案(它是关于找到从棋盘左上角到右下角的最短路径),但我已经三天没有遇到这种分段错误,我检查了我用过的每一个指针,一切似乎都正常。 我实现了“搜索算法”,bfs、dfs和ucs,前两个很好,但ucs给了我分割错误,尽管它们使用的是相同的东西,除了popBest函数。 以下是ucs和popBest功能的一些图片: Item *popBest( list_t *list ) // and remove the best
Item *popBest( list_t *list ) // and remove the best board from the list.
{
assert(list);
assert(list->numElements);
int min_f;
Item *item = list->first;
Item *best;
min_f = list->first->f;
while (item) {
if (item->f < min_f) {
min_f = item->f;
best = item;
}
item = item->next;
}
//item = onList(list, board);
delList(list, best);
return best;
}
void ucs(void)
{
Item *cur_node, *child_p, *temp;
while ( listCount(&openList_p) ) { /* While items are on the open list
printLt(openList_p );
/* Get the first item on the open list*/
cur_node = popBest(&openList_p);
//printf("%d %f\n", listCount(&openList_p), evaluateBoard( cur_node ));
printBoard(cur_node);
addFirst(&closedList_p, cur_node);
if ( evaluateBoard(cur_node) == 0.0 ) {
showSolution(cur_node);
printf("\nParcours en largeur (bfs)\n" );
return;
}
else {
for (int i = 0; i < MAX_BOARD; i++) {
child_p = getChildBoard( cur_node, i );
if (child_p != NULL) {
child_p->f = cur_node->f+1;
temp = onList(&openList_p, child_p->board);
if (temp ==NULL) addLast( &openList_p, temp);
else if (temp != NULL && child_p->f < temp->f )
{
delList(&openList_p, temp);
addLast( &openList_p, temp);
}
}
}
}
}
return;
}
Item*popBest(list\t*list)//并从列表中删除最佳线路板。
{
断言(列表);
断言(列表->数值);
国际货币基金组织;
项目*项目=列表->第一;
项目*最佳;
最小值=列表->第一个->f;
while(项目){
如果(项目->ff;
最佳=项目;
}
项目=项目->下一步;
}
//项目=在线列表(列表、板);
delList(列表,最佳);
回报最好;
}
无效ucs(无效)
{
项目*当前节点,*子节点,*温度;
while(listCount(&openList_p)){/*while项位于打开列表上
printLt(openList_p);
/*获取打开列表中的第一项*/
cur_node=popBest(&openList_p);
//printf(“%d%f\n”、listCount(&openList_p)、evaluateBoard(cur_节点));
印刷板(cur_节点);
addFirst(关闭列表和当前节点);
if(评估板(cur_节点)==0.0){
showSolution(当前节点);
printf(“\nParcures en largeur(bfs)\n”);
回来
}
否则{
对于(int i=0;if=当前节点->f+1;
temp=在线列表(&openList\u p,子\u p->board);
如果(temp==NULL)addLast(&openList\p,temp);
else if(temp!=NULL&&child\p->ff)
{
delList(和openList_p,temp);
addLast(和openList_p,temp);
}
}
}
}
}
回来
}
所有的函数都适用于bfs和dfs,唯一的区别是popBest函数。您可以执行
list->first->f
,而不检查list->first
是否为空指针
问题的原因可能是best
在循环后可能未初始化,如果列表中的第一个元素是“best”,则肯定会出现此问题
这是一个更安全的版本
Item *popBest( list_t *list )
{
assert(list);
assert(list->numElements);
assert(list->first);
// Assume that the first element is best.
Item *best = list->first;
int min_f = best->f;
// Search from the second element (if it exists).
Item* item = best->next;
while (item) {
if (item->f < min_f) {
min_f = item->f;
best = item;
}
item = item->next;
}
delList(list, best);
return best;
}
Item*popBest(列表)
{
断言(列表);
断言(列表->数值);
断言(列表->第一);
//假设第一个元素是最好的。
项目*最佳=列表->第一;
int min_f=最佳->f;
//从第二个元素(如果存在)进行搜索。
项目*项目=最佳->下一步;
while(项目){
如果(项目->ff;
最佳=项目;
}
项目=项目->下一步;
}
delList(列表,最佳);
回报最好;
}
请将您的代码引用转换为a。如果您做得正确,您可能会在途中找到答案。我几乎修复了错误的代码注释(与/*
到/
不匹配),但可能这是在您的实际代码中,因此您应该首先验证这一点,然后将实际代码粘贴到问题上(也要使其成为MCVE)。我会的,非常感谢。不,这不是我的,我想在写问题时编辑它,但在发布代码时我没有注意到。感谢测试是如果你运行你在这里发布的代码,并检查它是否再现了你的实际问题。如果你的真实代码在发布到这里之前需要一些编辑,那么在线编译器可以非常方便地创建mcve。例如,这里的代码没有编译(因此没有segfault):list->first
应该始终存在,如果list->numElements!=0
,那么best
应该始终存在。但是,如果第一个元素已经是best,那么该best
将被取消初始化,这是一个很好的观察结果。在您的示例中,尽管在一个包含单个元素的列表中它似乎是0(其中best->next
为0表示best==first
)。非常感谢您的评论,实际上listCount函数确保列表不为空(包含一项none NULL),当我编译时,它打印出第一块板,顶部有骑士,这意味着它确实会弹出第一个元素,但之后会出现分段错误。