2017-06-30 8 views
2

以下のプログラムは、ソートされた単一リンクリストから重複を削除するために使用されます。このコードは、オンラインIDEでガベージ値を示します。しかし、私はその行にコメントします。オンラインIDEとローカルIDEで異なる結果を出す同じコード

delete curr; 

プログラムは、オンラインIDE自体で正常に動作します。ここに私が書いた機能があります。コードの他の部分は、オンラインジャッジによって明確に定義されています(私ではありません)。

また、コメントなしのコードcurrを削除します。は、ローカルIDE(コードブロック)で正常に動作します。

FULL PROGRAM:http://ideone.com/9bHab0

は、なぜ私はゴミ値を得るのですか?

Node *removeDuplicates(Node *root) 
{ 
// your code goes here 
    struct Node* curr = root,*prev = NULL; 
    while(curr) 
    { 
     if(prev==NULL) 
      prev = curr; 
     else if(curr->data!=prev->data) 
      prev = curr; 
     else 
     { 
      prev->next = curr->next; 
      delete curr; 
      curr = prev->next; 
     } 
    } 
    return root; 
} 

EDIT:一つは、場所削除されたポインタを見ることができ、すぐに再割り当てされます。したがって、ここにぶら下がっているポインタはありませんでした!

+0

デバッガで実行してみましたか? –

+0

あなたは 'new'であなたの' Node'インスタンスを割り当てますか? *それらのすべて*?彼らのデストラクタは何をしていますか? –

+1

これは、C( 'struct Node * curr')とC++(' delete curr')コードがうまく混ざり合っています。あなたは、呼び出し元がC++で、インスタンスを割り当てるために 'operator new'を呼んでいますか? – IInspectable

答えて

4

非常に簡単な例ですが、2ノードのリストを使用してください。最初の反復で

node1 -> node2 

そしてprevはそうあなたがprev = currを行うNULLです。現在、currprevは同じノードを指しています。あなたはdelete currしかしcurrを指している。ここ

prev->next = curr->next; 
delete curr; 
curr = prev->next; 

を持って、両方のifの条件が偽である2回目の繰り返し(prev != NULLcurr->data == prev->data)あなたはelse部分に入る、手段

prevと同じメモリで、の未定義の動作が割り当て済みcurr = prev->nextになりました。これで、迷惑ポインタ。

さらに悪いことに、あなたはその後、prevはまだ削除された最初のノードを指し、そして再び(2番目のif状態で)無効prevポインタデリファレンスされ第三反復を入力して、あなたはもう一度に終わりますelse部分で無効な逆参照を続行します。そして、無限の中で(またはあなたがクラッシュする)。

+2

解決策は次のとおりです。 'prev = curr;を' prev = curr;に置き換えます。最初の2つの条件付きブランチではcurr = curr-> next; – IInspectable

+0

** curr = curr-> next **を** if部分に追加し、else if部分が**問題を解決しました。ソリューションに感謝します。私は質問のヘッダーを変更して、この質問に対する不注意な注意を避けるべきでしょうか? –

関連する問題