2009-05-30 1 views
-1

Метод jDeleteAfter класса связанного списка должен удалить узел сразу после узла, переданного в качестве аргумента. Если это так, я не знаю, но это внезапно закрывает консольное приложение, когда «delete tlp;» (Указатель списка тем). Мой инструктор, пользователи форума программирования, и мне еще предстоит определить корень этой проблемы.Почему «delete node;» сбой моего приложения C++ связанного списка?

Написан в 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] 

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

+0

Пожалуйста, переформатируйте исходный код с по крайней мере четырьмя (4) пробелами в начале каждой строки, чтобы сделать его более читаемым. –

+1

gdb - ваш друг ... –

+0

Erp, который не форматировал способ, которым я предназначался. Спасибо за редактирование. (scuttles off, чтобы читать о gdb) – 2009-05-30 22:06:00

ответ

2

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

+0

Нейл: игнорирование ошибок в памяти - это плохая практика. Не научите это новобраду, пожалуйста. Для того, чтобы «показать фрагмент кода в Интернете», это - хорошая вещь, чтобы избавиться от них. –

+4

В C++ лучше всего проигнорировать это - исключение будет выбрано. Отключение исключения, а затем не устранение ошибки, как это делает опрос, является наихудшей возможной практикой. – 2009-05-30 23:14:54

+0

Пока вы не на MSVC 6.0, у которого есть несовместимый оператор new, который возвращает NULL вместо метания. (Это может быть даже разорено в 2003 году, я не уверен). – ephemient

0

Некоторые советы Код обзор:

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 может быть реализовано неправильно. Рассмотрим случай, когда функция передается узлу ПЕРЕД хвостом. Я отрежу его там, потому что это выглядит как домашнее задание; но если у вас все еще есть проблемы, прокомментируйте, и я уточню.

EDIT: И я понял, что был неправ. Неважно!

0

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

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