Por que o “nó de exclusão;” falhar a minha candidatura lista C ++ ligados?
-
06-09-2019 - |
Pergunta
O método jDeleteAfter da minha classe lista encadeada é suposto para eliminar o nó imediatamente após o nó passado como um argumento. Se ele está fazendo isso, eu não sei, mas é abruptamente fechando a minha aplicação de consola quando "tlp de exclusão;" (Temp Lista Pointer) é lido. O meu instrutor, os usuários de um fórum de programação e eu ainda têm de determinar a raiz do problema.
Escrito em 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]
Eu uso a classe sentinela de busca para percorrer a lista e fornecer o nó adequado como um argumento para jDeleteAfter.
Nenhuma solução correta
Outras dicas
Uma dica simples: remover todos os testes para falha de alocação - que nunca vai acontecer em uma plataforma Windows amd complicar o código. E se eles acontecem, você não recuperar a partir deles, de modo que os testes são duplamente inútil.
Acontece que havia um conflito com a minha instrução de exclusão na minha destrutor virtual. Tudo funciona agora. Agradecimentos para o olhar-over do meu código.
Quanto aos nothrows - Eu faço-o assim porque nosso texto introduziu a idéia e eu não sei como lidar com exceções ainda. Obrigado pelo conselho, no entanto.
Alguns revisão de código dicas:
JawaLinkT* tlp; //new list node
if((tlp = new (nothrow) JawaLinkT) != NULL)
é mais legível como:
if(JawaLinkT* tlp = new (nothrow) JawaLinkT)
(também, ver o comentário de Neil acima porque usar nothrow sem realmente fazer nada sobre isso)
O código também está repleta de potenciais aleatória vazamentos de memória:
if((this->jHead = new (nothrow) JawaLinkT) && (this->jTail = new (nothrow) JawaLinkT))
// What if first new succeeds and second fails?
Quanto à questão, este é um monte de código para ler sem tanto como rastreamento de pilha para olhar para apenas um erro genérico, mas acho que jDeleteAfter pode ser implementado incorretamente. Considere o caso quando a função é passada o nó antes da cauda. Eu vou cortá-lo lá porque se parece com a lição de casa; mas se você ainda está tendo problemas, comentário e eu vou esclarecer.
EDIT: E eu percebi que estava errado. Nevermind!