Почему “удалить узел;” приводит к сбою моего приложения со связанным списком на C ++?

StackOverflow https://stackoverflow.com/questions/930693

  •  06-09-2019
  •  | 
  •  

Вопрос

Предполагается, что метод jDeleteAfter моего класса linked list удаляет узел, следующий сразу за узлом, переданным в качестве аргумента.Если он это делает, я не знаю, но он резко закрывает мое консольное приложение, когда считывается "удалить tlp;" (указатель временного списка).Моему преподавателю, пользователям форума по программированию и мне еще предстоит определить причину этой проблемы.

Написано на Dev-C ++ 4.9.9.2:

[source]
#include "JawaListT.h"
#include <cstdlib>
#include <iostream>
#include <new.h>

/*DEFAULT CONSTRUCTOR*/
JawaListT::JawaListT()
{
    if((this->jHead = new (nothrow) JawaLinkT) && (this->jTail = new (nothrow) JawaLinkT))
    {
        this->jHead->jSetNext(this->jTail);
        this->jTail->jSetNext(this->jTail);
    }//end if allocated
}

/*INSERT NODE AFTER*/
void JawaListT::jInsertAfter(JawaLinkT* lp, int val)
{
    if(lp != NULL && lp != this->jTail)     //if passed not tail and not null
    {
        JawaLinkT* tlp;             //new list node

        if((tlp = new (nothrow) JawaLinkT) != NULL) //if dynamically allocated  
        {
            tlp->jSetNext(lp->jGetNext());  //temp.next = passed.next                   
            lp->jSetNext(tlp);      //passed.next = temp
            tlp->jSetValue(val);        //temp.data = val
        }//end if allocated
    }//end if not tail
}

/*INSERT NODE BEFORE*/
void JawaListT::jInsertBefore(JawaLinkT* lp, int val)
{
    if(lp != NULL && lp != this->jHead)     //if passed not head and not null
    {
        JawaLinkT* tlp;             //new list node

        if((tlp = new (nothrow) JawaLinkT) != NULL) //if dynamically allocated
        {
            tlp->jSetNext(lp->jGetNext());
            tlp->jSetValue(lp->jGetValue());
//          *tlp = *lp;         //copies passed node to temp node
            lp->jSetNext(tlp);      //passed.next = temp
            lp->jSetValue(val);     //passed.data = val
            if(lp == this->jTail)       //if passed is tail
            {
                this->jTail = tlp;  //tail is temp
                this->jTail->jSetNext(this->jTail); //tail.next = tail
            }//end if lp
        }//end if tlp
    }//end if head
}

/*REMOVE NODE AFTER*/
void JawaListT::jDeleteAfter(JawaLinkT* lp)
{
    if(lp != NULL && lp->jGetNext() != this->jTail) //if not tail and not null
    {
        JawaLinkT* tlp;             //temp pointer to node

        tlp = lp->jGetNext();           //temp = passed.next
        lp->jSetNext(tlp->jGetNext());      //passed.next = temp.next
        delete tlp;             //delete to what temp points
    }//end if next  

        /*code that did not work any better*/
//      tlp->jSetNext((lp->jGetNext())->jGetNext());    
//      delete lp->jGetNext();
//      lp->jSetNext(tlp);

/*Also tried declaring and/or deleting tlp outside of decision structure, and
jDeleteCurrent(tlp) since that function works properly.*/   
}

/*REMOVE CURRENT NODE*/
void JawaListT::jDeleteCurrent(JawaLinkT* lp)
{
    if(lp != NULL && lp != jHead && lp != jTail)    //if not head or tail, not null
    {   
        JawaLinkT* tlp;             //temp pointer to node

        tlp = lp->jGetNext();           //temp = passed.next
        *lp = *tlp;             //copy temp to passed
        if(tlp == jTail)            //if temp is tail
        {
            this->jSetTail(lp);     //tail = passed
            lp->jSetNext(lp);       //passed.next = passed
        delete tlp;             //delete to what temp points
        }//end if tail
    }//end if not head
}

/*LINEAR SENTINEL SEARCH*/
JawaLinkT* JawaListT::jFindItemS(int item)
{
    JawaLinkT* tlp;                 //temp pointer to node
this->jTail->jSetValue(item);               //tail.data = item

    for(tlp = jHead->jGetNext(); tlp->jGetValue() != item; tlp = tlp->jGetNext());
    /*INIT: node after head, EXIT: data found, UPDATE: increment node*/

    if(tlp == jTail)                //if sentinel found
            std::cout << item << " not in list" << std::endl;   

    return((tlp != this->jTail->jGetNext()) ? tlp : NULL);
    /*If sentinel not found, return proper node, else return null*/
}

[/source]

Я использую класс sentinel search для обхода списка и предоставления соответствующего узла в качестве аргумента для jDeleteAfter.

Нет правильного решения

Другие советы

Простая подсказка:удалите все тесты на сбой распределения - они никогда не будут выполняться на платформе Windows и усложнят код.А если они все-таки случаются, вы от них не оправляетесь, так что тесты вдвойне бесполезны.

Оказывается, произошел конфликт с моим оператором delete в моем виртуальном деструкторе.Теперь все это работает.Спасибо за просмотр моего кода.

Что касается nothrows - я делаю это таким образом, потому что в нашем тексте представлена идея, и я пока не знаю, как обрабатывать исключения.Однако спасибо за совет.

Несколько советов по обзору кода:

JawaLinkT* tlp;                         //new list node

if((tlp = new (nothrow) JawaLinkT) != NULL)

более читабелен как:

if(JawaLinkT* tlp = new (nothrow) JawaLinkT)

(также смотрите комментарий Нила выше, почему он использует nothrow, фактически ничего с этим не делая)

Код также усеян случайными потенциальными утечками памяти:

if((this->jHead = new (nothrow) JawaLinkT) && (this->jTail = new (nothrow) JawaLinkT))
// What if first new succeeds and second fails?

Что касается вопроса, это большой объем кода для чтения без какой-либо трассировки стека, чтобы искать только общую ошибку, но я думаю, что jDeleteAfter может быть реализован неправильно.Рассмотрим случай, когда функции передается узел Перед хвостом.Я обрежу это здесь, потому что это действительно похоже на домашнее задание;но если у вас все еще возникают проблемы, прокомментируйте, и я уточню.

Редактировать:И я понял, что был неправ.Неважно!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top