簡體   English   中英

A* C 中的實現,分段錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM