¿Por qué “eliminar nodo;” chocar mi aplicación C ++ ligado lista?
-
06-09-2019 - |
Pregunta
Se supone que el método jDeleteAfter de mi clase de lista enlazada para eliminar el nodo inmediatamente después del nodo pasado como argumento. Si está haciendo eso, no sé, pero es bruscamente cerrando mi solicitud consola cuando "eliminar TLP;" (Temp lista de punteros) se lee. Mi instructor, los usuarios de un foro de programación y que todavía tienen que determinar la raíz de este problema.
Escrito en 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]
Yo uso la búsqueda de clases centinela para recorrer la lista y proporcionar el nodo adecuado como un argumento para jDeleteAfter.
No hay solución correcta
Otros consejos
Una sugerencia sencilla: eliminar todas las pruebas de error de asignación - que nunca va a pasar en una plataforma Windows amd complicar el código. Y si llegan a suceder, no recuperarse de ellos, por lo que las pruebas son doblemente inútil.
Resulta que había un conflicto con mi instrucción de eliminación en mi destructor virtual. Todo funciona ahora. Gracias por la mirada de posesión de mi código.
En cuanto a los nothrows - lo hago de esa manera porque nuestro texto introducido la idea y no sé cómo manejar excepciones todavía. Gracias por el consejo, sin embargo.
Algunos consejos de revisión de código:
JawaLinkT* tlp; //new list node
if((tlp = new (nothrow) JawaLinkT) != NULL)
es más fácil de leer como:
if(JawaLinkT* tlp = new (nothrow) JawaLinkT)
(también, véase el comentario de Neil por encima de por qué el uso nothrow sin hacer nada al respecto)
El código también está llena de pérdidas de memoria potencial al azar:
if((this->jHead = new (nothrow) JawaLinkT) && (this->jTail = new (nothrow) JawaLinkT))
// What if first new succeeds and second fails?
En cuanto a la cuestión, esto es una gran cantidad de código para leer sin tanto como seguimiento de la pila para buscar sólo un error genérico, pero creo que jDeleteAfter puede ser implementado de forma incorrecta. Considere el caso cuando la función se pasa el nodo antes de la cola. Voy a cortar fuera allí porque se parece a la tarea; pero si usted todavía tiene problemas, comentar y Voy a aclarar.
EDIT: Y me di cuenta que estaba equivocado. No importa!