[英]A* Implementation in C, Segmentation fault
對於C的一個學校項目,我想創建一個尋路算法,我決定使用A*。 經過長時間的反思和多次重寫所有代碼,我找不到問題所在。 一定是因為 memory 管理,但我不知道哪里出了問題。 即使在論壇上找了幾個小時后,我也沒有發現任何有趣的東西。
當 gdb 向我展示發生段錯誤的 function 時,他對我的幫助更大。
(gdb) bt
#0 0x0000000008000917 in list_prepend ()
#1 0x0000000008000b38 in findPath ()
#2 0x0000000008001473 in main ()
我使用 struct 來表示我的節點和指向節點的指針列表。
typedef struct Coord Coord;
struct Coord{
int x;
int y;
};
typedef struct Node{
bool walkable;
bool wayToGo;
Coord pos;
int gCost;
int hCost;
int fCost; // fCost = gCost + hCost
struct Node *parent;
} Node;
typedef struct NodeList{
Node * pNode;
struct NodeList * next;
struct NodeList * previous;
} NodeList;
以及提高 SIGSEGV 的 function:
NodeList * list_prepend(NodeList *old, Node *pNode)
{
NodeList *list = list_create(pNode);
if (list){
list->next = old;
old->previous = list;
}
return list;
}
在哪里:
NodeList * list_create (Node *pNode)
{
NodeList *list = malloc(sizeof(NodeList));
if (list)
{
list->pNode = pNode;
list->next = NULL;
list->previous = NULL;
}
return list;
}
我認為問題來自old->previous = list
,因為它看起來old->previous
給出了 NULL,我試圖影響 NULL。 我不知道,這就是我問的原因。
如果您有任何想法,或者如果您可以分享一個很好的調試技術,那就太好了。
如果需要,這里是我為測試探路者而編寫的完整代碼: pathFinding.c
NodeList * list_prepend(NodeList *old, Node *pNode)
{
NodeList *list = list_create(pNode);
if (list){
list->next = old;
(*old).previous = list; // Since this accesses *old, old cannot be NULL
}
return list;
}
請參閱上面的評論。 調用list_prepend
的前提條件是old
不是NULL
。
NodeList * getNeighbours(Node grid[row][column], Node * pNode)
{
int x, y;
NodeList * list = NULL;
for(x = -1; x <= 1; x++){
for(y = -1; y <= 1; y++){
if(x == y || x == -y)
continue;
int checkX = pNode->pos.x + x;
int checkY = pNode->pos.y + y;
if (checkX >= 0 && checkX < column && checkY >= 0 && checkY < row){
list = list_prepend(list, &(grid[checkY][checkX])); // Uh oh, list is NULL on first invocation
}
}
}
return list;
}
見評論。 第一次調用list_prepend
違反了先決條件。 清楚地記錄(在評論中)您的功能的先決條件非常重要。 測試所有前提條件是否為真並報告任何不正確的條件也非常有幫助。 它使調試更容易。
我也對你在幾個地方的想法感到困惑。 例如:
NodeList * list_append(NodeList *list, Node *pNode)
{/*Rajouter le previous*/
NodeList **plist = &list;
while (*plist)
plist = &(*plist)->next;
*plist = list_create(pNode);
if (*plist)
return list;
else
return NULL;
}
為什么plist
中的雙重間接混亂? 為什么不設置新創建節點的prev
? 為什么不只是:
NodeList * list_append(NodeList *list, Node *pNode)
{
if (list == NULL)
return list_create(pNode);
NodeList *plist = list;
while (plist->next != NULL)
plist = plist->next;
plist->next = list_create(pNode);
if (plist->next == NULL)
return NULL;
plist->next->prev = plist;
return list;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.