Нарушение прав чтения при попытке удалить один узел из односвязного списка C ++ - PullRequest
0 голосов
/ 11 октября 2019

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

template <class dataType>
bool UnOrderedList<dataType>::remove(int remove) {
    Node<dataType>* current = head;
    Node<dataType>* copy = head;
    Node<dataType>* trail = nullptr;

    if (current == nullptr) {
        return false;
    }

    if (head->data == remove) {
        Node<dataType>* temp = head;
        head = head->next;
        delete temp;
        return true;
    }

    while (current != nullptr) {
        trail = current;
        if (current->data == remove) { // error occurs on this line
            Node<dataType>* temp2 = current;
            current = trail->next;
            delete temp2;
            return true;
        }
        current = current->next;
    }
    return false;

}

Iпрокомментировал строку, в которой происходит ошибка. Visual Studio говорит: «Возникло исключение: нарушение прав на чтение. Текущий был 0xDDDDDDDD.»

Есть ли что-то, что я делаю не так? Я хотел бы знать, как я могу избежать этого в будущем. Мне интересно узнать больше об указателях и как они работают. Спасибо за любую помощь!

Ответы [ 2 ]

2 голосов
/ 11 октября 2019

При удалении узла вы не обновляете указатель next предыдущего узла. В следующий раз через цикл вы получите доступ к этому висячему указателю и прочтете память, которая была освобождена (для Visual C ++ установлено значение 0xDDDDDDDD).

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

0 голосов
/ 11 октября 2019

Как упоминал JaMiT, трудно отладить без возможности воспроизведения. Обратите внимание на несколько предложений

  1. Вы никогда не используете copy.

  2. Поведение в следующей части

while (current != nullptr) {
    trail = current;
    if (current->data == remove) { // error occurs on this line
        Node<dataType>* temp2 = current;
        current = trail->next;
        delete temp2;
        return true;
    }
    current = current->next;
}

действительно выглядит как то, что вы хотели бы сделать. Когда вы входите в цикл в первый раз, trail и current - это одно и то же (потому что вы присваиваете current для trail). Если current узел не был узлом, который нужно удалить, вы делаете current = current->next;. Предполагая, что это не nullptr, вы возвращаетесь к началу цикла и снова устанавливаете trail на current. Возможно, вы захотите установить trail на старое current (чтобы trail следовало за current, как следует из названия).

while (current != nullptr) {
    if (current->data == remove) {
        Node<dataType>* temp2 = current;//save pointer to the node to delete later
        trail->next = current->next;//skip this node - deleting it from the chain
        delete temp2;//delete it
        return true;
    }
    trail = current; //let trail follow current
    current = current->next;
}
Почему remove для UnOrderedList<dataType> принимает int вместо dataType?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...