在链表中插入元素(Project InsertElement引发了异常类'External:SIGSEGV')

时间:2018-01-25 12:30:51

标签: pointers linked-list pascal

我编写了这个程序,它应该从用户输入创建一个整数的链接列表,直到用户插入'0',打印它,在它的末尾添加一个元素,然后再次打印链表,包括添加元素。

当我运行它时,输入和第一个输出工作正常,但是当添加新元素时,我收到以下错误消息:

  

“Project InsertElement引发异常类'外部:SIGSEGV'中   第66行的文件'InsertElement.lpr':OutRefEnd ^ .next:= RefNew;“

显然,第66行存在问题:

OutRefEnd^.next := RefNew;

但是我无法弄清楚那个问题是什么,如果它与我的代码有关,或者它只是编译器。根据我的理解,错误代码暗示'outRefEnd ^ .next'`指向一个空地址,但由于我将其赋值为'RefNew',我不太明白为什么这应该是第一个问题的地方。

有人可以给我一个关于我哪里出错的提示吗?

这是我的代码:

program InserElement(input, output);
    {Has the user type in integers and forms a linked list out of them,
    then inserts an element at the end of that linked list and prints the
    linked list with the added new element}

    {$mode objfpc}{$H+}

    uses
      {$IFDEF UNIX}{$IFDEF UseCThreads}
      cthreads,
      {$ENDIF}{$ENDIF}
      Classes;

    type
      tRefList = ^tList;
      tList = record
                 info : integer;
                 next : tRefList
                end;
    var
     RefBeginning: tRefList;
     RefEnd : tRefList;
     Pointer : tRefList;
     Number : integer;



       procedure CreateList( var outRefBeginning: tRefList);
       { Creates a linear list through user input }


      begin
       readln(Number);
       while Number <> 0 do
       begin
         new (Pointer);
         Pointer^.info := Number;
         Pointer^.next := outRefBeginning;
         outRefBeginning := Pointer;
         readln (Number)
       end { while-loop }
      end; {CreateList}

    procedure InsertElement(inNumber : integer; var outRefBeginning : tRefList; var outRefEnd : tRefList);
      { Inserts a new element at the end of the list. outRefBeginning points to the first
      element of that list, outRefEnd points to the last element of it. The Value of inNumber is
      assigned to the record component info of the new element}

      var
       RefNew : tRefList;

      begin
      { Create and initialise new element }
      new(RefNew);
      RefNew^.info := inNumber;
      RefNew^.next := nil;
      { Insert element at the end of the linear list }
      if outRefBeginning = nil then
         begin
         outRefBeginning := RefNew;
         outRefEnd := RefNew
         end
         else
             begin
               outRefEnd^.next := RefNew;
               outRefEnd := RefNew;
             end;
      end;{ InsertElement }

      procedure PrintList;
      { Prints all elements of the linked list }

      var
       RefNew : tRefList;

      begin
       RefNew := RefBeginning;
       while RefNew <>  nil do
       begin
         writeln (RefNew^.info);
         RefNew := RefNew^.next
       end;
      end;

    begin
      RefBeginning := nil;
      RefEnd := RefBeginning;
      CreateList(RefBeginning);
      PrintList;
      InsertElement(5,RefBeginning,RefEnd);
      PrintList;
      readln;
    end.

[编辑] 对于任何有兴趣的人,我会粘贴下面的更正代码,我根据汤姆答案中的建议进行了更改。

的变化:

  1. 我删除了指针变量,因为它不再需要:

    var
     RefBeginning: tRefList;
     RefEnd : tRefList;
     Number : integer;
    
  2. 我将procedure CreateList更改为类似于procedure InsertElement,因为它不仅在RefBeginning中保存了新元素的值,还在RefEnd中保存了该值:

     procedure CreateList(var outRefBeginning: tRefList; var OutRefEnd:  tRefList);
           { Creates a linear list through user input }
          var
           RefNew : tRefList;`
    
      begin
       writeln('Please key in natural numbers. Key in 0 once you are done. ');
       readln(Number);
       while Number <> 0 do
       begin
         new (RefNew);
         RefNew^.info := Number;
         RefNew^.next := nil;
         if outRefBeginning = nil then
          begin
          outRefBeginning := RefNew;
          OutRefEnd := RefNew;
          end
         else
         begin
           outRefEnd^.next := RefNew;
           outRefEnd := RefNew
         end;
         readln (Number)
       end; { while-loop }
      end; {CreateList}   
    

    最后但并非最不重要的,这是完整的代码:

    program InserElement(input, output);
        {Has the user type in integers and forms a linked list out of them,
        then inserts an element at the end of that linked list and prints the
        linked list with the added new element}
    
    {$mode objfpc}{$H+}
    
    uses
      {$IFDEF UNIX}{$IFDEF UseCThreads}
      cthreads,
      {$ENDIF}{$ENDIF}
      Classes;
    
    type
      tRefList = ^tList;
      tList = record
                 info : integer;
                 next : tRefList
                end;
    var
     RefBeginning: tRefList;
     RefEnd : tRefList;
     Number : integer;
    
    
    
       procedure CreateList(var outRefBeginning: tRefList; var OutRefEnd: tRefList);
       { Creates a linear list through user input }
      var
       RefNew : tRefList;
    
      begin
       writeln('Please key in natural numbers. Key in 0 once you are done. ');
       readln(Number);
       while Number <> 0 do
       begin
         new (RefNew);
         RefNew^.info := Number;
         RefNew^.next := nil;
         if outRefBeginning = nil then
          begin
          outRefBeginning := RefNew;
          OutRefEnd := RefNew;
          end
         else
         begin
           outRefEnd^.next := RefNew;
           outRefEnd := RefNew
         end;
         readln (Number)
       end; { while-loop }
      end; {CreateList}
    
    procedure InsertElement(inNumber : integer; var outRefBeginning : tRefList; var outRefEnd : tRefList);
      { Inserts a new element at the end of the list. outRefBeginning points to the first
      element of that list, outRefEnd points to the last element of it. The Value of inNumber is
      assigned to the record component info of the new element}
    
      var
       RefNew : tRefList;
    
      begin
      { Create and initialise new element }
      new(RefNew);
      RefNew^.info := inNumber;
      RefNew^.next := nil;
      { Insert element at the end of the linear list }
      if outRefBeginning = nil then
         begin
         outRefBeginning := RefNew;
         outRefEnd := RefNew
         end
         else
             begin
               outRefEnd^.next := RefNew;
               outRefEnd := RefNew;
             end;
      end;{ InsertElement }
    
      procedure PrintList;
      { Prints all elements of the linked list }
    
      var
       RefNew : tRefList;
    
      begin
       RefNew := RefBeginning;
       while RefNew <>  nil do
       begin
         writeln (RefNew^.info);
         RefNew := RefNew^.next
       end;
      end;
    
    begin
      RefBeginning := nil;
      RefEnd := nil;
      CreateList(RefBeginning, RefEnd);
      InsertElement(5,RefBeginning,RefEnd);
      PrintList;
      readln;
    end.
    

1 个答案:

答案 0 :(得分:0)

您在procedure CreateList();中出错了,因为您将新记录添加到开头而不是结尾。 RefEnd之后nil仍为CreateList()

当您使用InsertElement(5,RefBeginning,RefEnd);致电RefEnd = nil时,会在outRefEnd^.next := RefNew;行触发错误,因为参数outRefEnd为零。

关于将初始项目与CreateList()InsertElement以及后续新项目关联到{{1>,您应该更正outRefBeginning程序,使其基本上与outRefEnd类似。 }}