Pourquoi est-ce « nœud supprimer, » planter ma demande de liste chaînée C ++?
-
06-09-2019 - |
Question
La méthode jDeleteAfter de ma classe de liste chaînée est censé supprimer le noeud suivant immédiatement le nœud passé comme argument. Si ce fait, je ne sais pas, mais il est brusquement ma demande fermais la console « pour supprimer TLP; » (Temp Liste pointeur) est lu. Mon instructeur, les utilisateurs d'un forum de programmation et je dois encore déterminer la racine de ce problème.
écrit dans 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]
J'utilise la recherche sentinelle de classe pour parcourir la liste et fournir le nœud approprié comme argument pour jDeleteAfter.
Pas de solution correcte
Autres conseils
Un conseil simple: supprimer tous les tests de l'échec de l'allocation - ils ne se produira jamais sur une plate-forme Windows amd compliquer le code. Et si elles se produisent, vous ne récupérez pas d'eux, de sorte que les tests sont doublement inutiles.
Il se trouve qu'il y avait un conflit avec ma déclaration de suppression dans mon destructor virtuel. Tout fonctionne maintenant. Merci pour le look plus de mon code.
En ce qui concerne les nothrows - je le fais de cette façon parce que notre texte introduit l'idée et je ne sais pas comment gérer encore des exceptions. Merci pour les conseils, cependant.
Quelques conseils de révision du code:
JawaLinkT* tlp; //new list node
if((tlp = new (nothrow) JawaLinkT) != NULL)
est plus lisible que:
if(JawaLinkT* tlp = new (nothrow) JawaLinkT)
(également, voir le commentaire de Neil ci-dessus en utilisant pourquoi nothrow sans faire quoi que ce soit à ce sujet)
Le code est également jonché de fuites de mémoire potentiel aléatoires:
if((this->jHead = new (nothrow) JawaLinkT) && (this->jTail = new (nothrow) JawaLinkT))
// What if first new succeeds and second fails?
Quant à la question, cela est beaucoup de code à lire sans tant que trace de la pile pour chercher juste un bug générique, mais je pense que jDeleteAfter peut être mis en œuvre de manière incorrecte. Considérons le cas où la fonction est transmise au noeud avant de la queue. Je vais arrêter ici parce qu'il n'a pas l'air comme les devoirs; mais si vous rencontrez toujours des problèmes, des commentaires et je vais préciser.
EDIT: Et je me suis aperçu que je me suis trompé. Nevermind!