私のC ++リンクリストアプリケーションをクラッシュ;なぜ「ノードを削除する」のでしょうか?
-
06-09-2019 - |
質問
私のリンクリストクラスのjDeleteAfterメソッドは、引数として渡されたノードの直後のノードを削除することになっています。それがあることを行っている場合、私は知らないが、ときそれは突然私のコンソールアプリケーションを閉じている「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]
私はリストを横断し、jDeleteAfterの引数として適切なノードを提供するために、クラスのセンチネル検索を使用します。
正しい解決策はありません
他のヒント
簡単なヒント:割り当て失敗のためにすべてのテストを削除する - 彼らは、Windowsプラットフォーム上で起こりませAMDのコードを複雑ありません。彼らが起こるならばテストが二重に役に立たないように、あなたは、彼らから回復しません。
これは、私の仮想デストラクタで、私の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が正しく実装されてもよいと思います。関数が尾前に、ノードを渡された場合を考えてみましょう。それは宿題のように見えるんので、私はそこにそれをカットします。それでも問題が解決している場合は、コメントと私は明確でしょう。
編集:私は私が間違っていた実現。ネヴァーマインド!