0

これは、並べ替えられたリンク リストへの順序付き挿入を行うためのクラス割り当てです。null ポインターへのアクセスを回避し、デバッグ出力の行をいくつか追加して、seg fault を while ループ自体の条件ステートメントに絞り込みました。

空のリストにノードを追加し、より小さなキーを持つノードをリストの先頭に追加できますが、空でないリストの最後にキーを追加すると、セグ フォールトが発生します。デバッグ出力で示されているように、問題のある while ループは、cursor->next == NULL になるまで正常に循環します。それがセグフォルトをスローするときです。私が知る限り、空のポインターにアクセスしようとしていません。私は本当にかなり困惑しており、助けていただければ幸いです。ありがとう!

以下のコードで厄介な行を示しました。

// Headers
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

struct Node {
  int id;
  string initials;
  double score;
  Node* next;
};
const int ESC = -9999;
const int ID_LIMIT = 1000000000;

int main(){  
  // initialize variables
  int temp_id = 0;  // temporary input
  Node* Start=NULL; // first node in linked list

  // get input until escape value is entered or input stream fails
  while ( temp_id != ESC && !cin.fail() ){
    cout << "\nPlease enter the student id, or "
         << ESC << " to finish inputing: ";
    cin >> temp_id;
    if ( temp_id >=0 && temp_id < ID_LIMIT ) { 
      // if valid input, continue input & create node
      string temp_inits;
      double temp_score;
      cout << "Please enter the student initials: " ;
      cin >> temp_inits;
      cout << "Please enter the student's test score: " ;
      cin >> temp_score;

      // create new node with input values
      Node* temp = new Node;
      temp->id = temp_id;
      temp->initials = temp_inits;
      temp->score = temp_score;
      temp->next = NULL;

      // TASK 4: SORTED INPUT
      if ( Start == NULL ) {  // if first node to be input
        Start = temp;         // point the first pointer to it
      }else{                  // otherwise
        if( temp->id < Start->id ){  // if new node should go before Start,
          temp->next = Start;        // move start after temp
          Start = temp;              // and reassign Start
        }else{
          Node* cursor = Start; // parse list for proper place or end
          cout << "\nDEBUG: while ( cursor-id:" << cursor->id ;
          cout << " < temp-id:" << temp->id;
          cout << " && cursor-next:" << cursor->next << " != NULL )";
// I THINK THE NEXT LINE IS THE CULPRIT
          while ( cursor->id < temp->id && cursor->next != NULL ) {
            cout << "\nDEBUG: { old cursor:" << cursor->id ;
            cursor = cursor->next;
            cout << ", new cursor:" << cursor->id << " }";
            cout << "\nDEBUG: while ( cursor-id:" << cursor->id ;
            cout << " < temp-id:" << temp->id;
            cout << " && cursor-next:" << cursor->next << " != NULL )";
          }
          cout << "\nDEBUG: insert temp-id:" << temp->id 
               << " after cursor-id:" << cursor->id ;
          temp->next = cursor->next;
          cursor->next = temp;  // inject new node into list.
          cursor = temp->next;
          cout << " before id " << cursor->id;
        }
      }
      cout << "Node with id=" << temp->id << ", initials=" << temp->initials 
           << ", and test score=" << temp->score << " added to the list.\n";

    }else{ // if invalid input & not escape value, print error
      if ( temp_id != ESC ) cout << "!!! Invalid input !!!\n";
    }   
  }

  return 0;
}

出力:

Please enter the student id, or -9999 to finish inputing: 654
Please enter the student initials: abc
Please enter the student's test score: 99.9
Node with id=654, initials=abc, and test score=99.9 added to the list.

Please enter the student id, or -9999 to finish inputing: 312
Please enter the student initials: qwe
Please enter the student's test score: 54.8
Node with id=312, initials=qwe, and test score=54.8 added to the list.

Please enter the student id, or -9999 to finish inputing: 987
Please enter the student initials: rty
Please enter the student's test score: 87.5

DEBUG: while ( cursor-id:312 < temp-id:987 && cursor-next:0x1c26040 != NULL )
DEBUG: { old cursor:312, new cursor:654 }
DEBUG: while ( cursor-id:654 < temp-id:987 && cursor-next:0 != NULL )
Segmentation fault

私もループを試しまし( ... cursor->next != 0 )( ... cursor->next )

4

2 に答える 2

1
  while ( cursor->id < temp->id && cursor->next != NULL )
  {
      cursor = cursor->next;
  }

  temp->next = cursor->next;
  cursor->next = temp;  // inject new node into list.
  cursor = temp->next;
  cout << " before id " << cursor->id;

ループがcursor最後のノードを指すまで実行されると、 cursor->nextnullになります。新しいノードを挿入した後(私には間違った場所にあるように見えますが、関係ありません)、新しいノードは最後でありtemp->next、nullpointerとして使用されます。次にnullにcursor = temp->next設定cursorすると、次のデバッグ出力ステートメントがcursorクラッシュcursor->idします。

確かに、デバッガーで実行する必要があります。

そして、それは私があなたに持っている1つの強力な提案です:頭脳だけでなくデバッガーを使用してください。:-)

2番目の強力な提案:抽象化を使用し、目に見えるすべてのものに名前を付けます。これは、たとえばリストの挿入など、小さな関数を定義することを意味します。そうすれば、物事を分析する方がはるかに簡単です。

于 2012-02-22T00:18:02.507 に答える
0

問題は、while() ループから抜け出した後です。

  1>    temp->next = cursor->next;
  2>    cursor->next = temp;  // inject new node into list.
  3>    cursor = temp->next;
  4>    cout << " before id " << cursor->id;

cursor->next == null (リストの最後) で上記の行に到達し、temp->next も null です。したがって、この場合、1 行目は何もしません。行 2 は、temp のアドレスを cursor->next にコピーします。この時点で、次のことがわかります。

temp: temp の元のアドレス、temp->next == NULL cursor: カーソルの元のアドレス、cursor->next == temp の元のアドレス

次に、temp->next をカーソルにコピーしますが (うーん!)、temp->next は null なので、カーソルは null になります。したがって、4行目を実行してcursor->idを取得すると、「null->id」を読み取ろうとしてクラッシュします。

于 2012-02-22T00:47:46.233 に答える