Ошибка переполнения стека, несмотря на выделение кучи (C) - PullRequest
0 голосов
/ 11 февраля 2019

В настоящее время я работаю над программой, которая должна решать 10x10 лабиринт, например, такой:

      1   2   3   4   5   6   7   8   9  10
___________________________________________
 1|   +  []   +  []   +  []   +   +   +  []
 2|   +  []   +   +  []   +   +  []  []  []
 3|   +   +  []  []  []   +  []  []   +   +
 4|  []  []  []  []   +   +   +  []  []   +
 5|   +  []   +  []   +  []   +   +   +  []
 6|   +   +   +   +   +   +  []  []   +  []
 7|  []   +   +   +  []  []   +   +   +  []
 8|   +   +   +  []   +   +   +  []  []   +
 9|   +   +   +  []  []   +   +  []  []   +
10|   +  []   +  []   +   +  []   +   +   +

Игнорировать числа, они просто координаты.Что касается [], это просто способ печати лабиринта.На самом деле, где есть +, то это означает путь, где [] означает, что есть препятствие.

Я использую алгоритм возврата:

void backtrack(int curX, int curY, char(*char_maze)[10], int position)
{
    if (curX < 0 || curY < 0 ||
        curX > 9 || curY > 9) {
        //out of bounds
        return;
    }
    Node tmp;
    tmp.x = curX, tmp.y = curY;
    queue(&head, &tmp);
    position++;
    if (char_maze[curX][curY] == finish) {
        //destination found TODO print path
        printf("route found");
    }
    if (char_maze[curX][curY] == path) {
        char_maze[curX][curY] = visited;
    }
    backtrack(curX, curY - 1, char_maze, position);
    backtrack(curX - 1, curY, char_maze, position);
    backtrack(curX, curY + 1, char_maze, position);
    backtrack(curX + 1, curY, char_maze, position);

    char_maze[curX][curY] = path;
    if (position) {
        del_nth(head, position);
    }
    if (!position) {
        del_first(&head);
    }
    position--;
}

Правильный маршрутбудет состоять из связанного списка, вот узел этого списка:

typedef struct coords {
    int     x;
    int     y;
    struct coords * next;
}Node;

всякий раз, когда backtrack(...) натыкается на проходимую ячейку, он должен пометить его как посещенный и добавить в список.Добавление в список осуществляется с помощью этих 2 функций:

void queue(Node ** head, Node * object)
{
    Node * tmp = (Node *)malloc(sizeof(Node)); //this is the problematic line
    *tmp = *object;
    Node * last = get_last(*(head));
    if (!last) {
        (*head) = tmp;
        tmp->next = NULL;
    }
    else {
        last->next = tmp;
        tmp->next = NULL;
    }
}

и

Node * get_last(Node * head)
{
    while (1) {
        if (head) {
            head = head->next;
        }
        else {
            return NULL;
        }
    }
return head;
}

, а также при соответствующих условиях backtrack(...) следует снять отметку с ячейки и удалить ее из списка.Удаление выполняется с помощью этих двух функций:

void del_nth(Node * head, int index)
{
    Node * previous;
    for (int i = 0; i < index - 1; i++) {
        head = head->next;
    }
    previous = head;
    head = head->next;
    previous->next = head->next;
    free(head);
}

и

void del_first(Node ** head)
{
    Node * del = (*head);
    (*head) = (*head)->next;
    free(del);
}

path, visited, finish и т. Д. const char -s, которые представляют ячейки лабиринта.

backtrack(...)

вызывается с 2-мя координатами, установленными пользователем, с самим лабиринтом и position, для которого установлено 0.

Теперь, когда я объяснил, как работает код, проблема.Я прогнал этот код через отладчик Visual Studio и получил исключение Stack overflow (parameters: 0x00000001, 0x00492FFC). в этой строке

Node * tmp = (Node *) malloc(sizeof(Node)); 

, которое является частью функции queue(...).Это не имеет никакого смысла для меня, так как malloc() выделяет в куче.Я в тупике, у меня нет объяснений, я понятия не имею, почему это происходит.Я включил весь код, используемый в функции backtrack(...), потому что проблема действительно может быть.Это был бы не первый случай, когда отладчик указал неверную строку.В любом случае, большое спасибо за вашу помощь заранее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...