代码之家  ›  专栏  ›  技术社区  ›  Lucky

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

  •  0
  • Lucky  · 技术社区  · 6 年前

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

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

    “Project InsertElement在中引发了异常类‘External:SIGSEGV’” 文件“InsertElement”。第66行的lpr:输出端^。下一步:=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.
    

    [编辑] 对于任何感兴趣的人,我将粘贴下面更正的代码,我根据Tom答案中的建议更改了代码。

    变化:

    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 回复  |  直到 6 年前
        1
  •  0
  •   Tom Brunberg    6 年前

    你在 procedure CreateList(); 您可以在开头而不是结尾添加新记录。 RefEnd 仍然是 nil 之后 CreateList() .

    当你打电话的时候 InsertElement(5,RefBeginning,RefEnd); 具有 RefEnd = nil 该错误在线路上触发 outRefEnd^.next := RefNew; 作为参数 outRefEnd 为零。

    您应该更正 CreateList() 基本工作程序类似于 InsertElement 关于将初始项链接到 outRefBeginning 输出端 以及后续的新项目 输出端 .