2009-05-30 5 views
-1

リンクリストクラスのjDeleteAfterメソッドは、引数として渡されたノードの直後のノードを削除することになっています。それがやっているのか分かりませんが、 "delete tlp;"が表示されたときに私のコンソールアプリケーションを突然閉じてしまいます。 (Temp List Pointer)が読み込まれます。私のインストラクター、プログラミングフォーラムのユーザーで、私はまだこの問題の根本を特定していません。 4.9.9.2 ++のDev-Cで書かれなぜ「ノードを削除しますか?」私のC++リンクリストアプリケーションをクラッシュさせますか?

[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は、私が意図した方法でフォーマットしませんでした。編集していただきありがとうございます。 (gdbについて読むために解読する) –

答えて

2

単純なヒント:割り当ての失敗のテストをすべて削除します。これらのテストはWindowsプラットフォームでは起こりません。コードが複雑になります。彼らが起こった場合、あなたはそれらから回復しないので、テストは二重に役に立たない。

+0

Neil:メモリ不足のエラーを無視するのは悪いことです。新生児に教えてください。 「インターネットへのコードスニペットを表示する」ために、それを取り除くのは良いことです。 –

+4

C++では、例外を無視することをお勧めします。例外がスローされます。例外を無効にしてから、エラーを処理しない場合は、質問者のように、最悪の場合があります。 –

+0

あなたがMSVC 6.0にいない限り、スローではなくNULLを返す新しい準拠の演算子newがあります。 (2003年に逮捕される可能性もありますが、わかりません) – ephemient

0

いくつかのコードレビューのヒント:

if(JawaLinkT* tlp = new (nothrow) JawaLinkT) 

(また、実際にはそれについて何もせずにnothrowを使用して、なぜ上記のニールさんのコメントを参照してください)

JawaLinkT* tlp;       //new list node 

if((tlp = new (nothrow) JawaLinkT) != NULL) 

は、より読みやすいですコードはランダムな潜在的メモリリークで散らばっています:

if((this->jHead = new (nothrow) JawaLinkT) && (this->jTail = new (nothrow) JawaLinkT)) 
// What if first new succeeds and second fails? 

質問によれば、これは一般的なバグを探すためにスタックトレースなしで読み込むコードがたくさんありますが、jDeleteAfterが正しく実装されていない可能性があります。関数がテールの前にノードを通過する場合を考えてみましょう。それは宿題のように見えるので、私はそれを切り捨てます。あなたがまだ問題を抱えている場合は、コメントしてください。

編集:私は間違っていたことに気付きました。気にしないで!

0

仮想デストラクタのdelete文と競合が発生していることが判明しました。それはすべて今働く。私のコードを見ていただきありがとうございます。

私たちのテキストがこのアイデアを紹介し、例外処理の仕方がまだわからないので、私はそうしません。しかし、アドバイスをいただきありがとうございます。

関連する問題