Почему деструктор попадает в нераспределенную память? - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть односвязный круговой связанный список, и я пишу деструктор для удаления всех узлов. Деструктор сначала отсекает голову от остальной части, чтобы предотвратить бесконечную циркуляцию, а затем я пропускаю через список l oop и удаляю все узлы, в конце концов, l oop возвращается к голове и удаляет ее. В программе я проверяю, чтобы убедиться, что указатель на узлы не равен NULL, и я запустил отладчик, и он показывает, что он равен NULL в точке, которая должна завершить l oop, но вместо этого l oop продолжается и работает в нераспределенной памяти. Вот мой код:

    node<T> *cur = head;
    node<T> *nxt = head->next;
    if (nxt) cur->next = nullptr;
    cur = nxt;

    // walk through the list and delete nodes
    while (cur) {
        cur = cur->next;
        delete cur;
    }

РЕДАКТИРОВАТЬ: Изменен код на

  node<T> *cur = head;
    node<T> *nxt = head->next;
    if (nxt) cur->next = nullptr;
    cur = nxt;

    // walk through the list and delete nodes
    while (cur) {
        nxt = cur->next;
        delete cur;
        cur = nxt;
    }

РЕДАКТИРОВАТЬ 2: Еще раз изменен код для обработки края случаев, такая же проблема все еще возникает.

if (head ==  NULL) return;
    else if (head->next == head) delete head;
    else {
        node<T> *cur = head;
        node<T> *nxt = head->next;
        cur->next = nullptr;
        cur = nxt;
        while(cur) {
            nxt = cur -> next;
            delete cur;
            cur = nxt;
        }
    }

1 Ответ

2 голосов
/ 06 апреля 2020

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

Вам необходимо удалить элемент текущий (но, конечно, вам также необходимо чтобы извлечь его next поле до этой точки, потому что после удаления все содержимое становится неопределенным), что-то вроде:

while (cur != nullptr) {
    node<T> *toDelete = cur;
    cur = cur->next;
    delete toDelete;
}

С точки зрения полного решения того, что вам нужно, алгоритм должен быть:

def delCircList(head):
    # Ignore empty list.

    if head == null:
        return

    # Special for one-element list.

    if head.next == head:
        free head
        return

    # Sever link and set start point.

    curr = head.next
    head.next = null

    # Use normal deletion algorithm.

    while curr != null:
        toDelete = curr
        curr = curr.next
        free toDelete
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...