0

这是一个对有序链表进行有序插入的类分配。我已经避免访问空指针,并且我添加了一些调试输出行以将 seg 错误缩小到 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->next则为空。插入新节点后(在我看来,在错误的位置,但没关系),新节点是最后一个并且具有temp->next空指针。然后cursor = temp->next设置cursor为 null,随后的调试输出语句,取消引用cursorvia cursor->id,崩溃。

可以肯定的是,我应该在调试器中运行它。

这是我给你的一个强烈建议:使用调试器,而不仅仅是大脑。:-)

第二个强烈建议:使用抽象,命名几乎所有可见的东西。这意味着定义小函数,例如用于列表插入。那时分析事物要容易得多。

于 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 复制到 cursor(uhoh!),但是 temp->next 为 null,所以 cursor now 为 null。因此,当您执行第 4 行并获取 cursor->id 时,它会尝试读取“null->id”并崩溃。

于 2012-02-22T00:47:46.233 回答