You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

链表插入元素触发SIGSEGV异常 求问题排查指引

解决Pascal链表尾部插入时的SIGSEGV异常问题

你遇到的External: SIGSEGV错误本质是空指针解引用,核心问题出在你的CreateList过程没有正确维护链表的尾指针RefEnd,具体原因如下:

  • 原CreateList采用头插法构建链表,但只更新了头指针outRefBeginning,完全没有对尾指针RefEnd做任何更新操作。
  • 主程序中你初始化RefEnd := RefBeginning(也就是nil),之后CreateList运行全程都没修改过RefEnd,所以当你调用InsertElement时,传入的outRefEnd仍然是nil。
  • 此时因为链表已经有元素,InsertElement会进入else分支,执行outRefEnd^.next := RefNew——这相当于对空指针进行解引用,直接触发段错误。

修正方案

我们需要让CreateList过程同时维护头指针和尾指针,改用尾插法构建链表(天然适合维护尾指针),同时清理不必要的全局变量:

具体修改点

  • 移除全局的Pointer变量,改用局部变量避免全局状态带来的意外问题
  • 重写CreateList过程,添加尾指针参数,用尾插法构建链表,同步更新头、尾指针
  • 主程序中正确初始化并传递RefEnd参数给CreateList

修正后的完整代码

program InserElement(input, output); 
{让用户输入整数构建链表,随后在链表尾部插入元素并打印包含新元素的链表}
{$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);
{通过用户输入创建线性链表}
var
  RefNew : tRefList;
begin
  writeln('请输入自然数,输入0结束输入。');
  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);
{在链表尾部插入新元素。outRefBeginning指向链表首元素,outRefEnd指向链表尾元素,inNumber赋值给新元素的info字段}
var
  RefNew : tRefList;
begin
  {创建并初始化新元素}
  new(RefNew);
  RefNew^.info := inNumber;
  RefNew^.next := nil;
  {在线性链表尾部插入元素}
  if outRefBeginning = nil then begin
    outRefBeginning := RefNew;
    outRefEnd := RefNew
  end else begin
    outRefEnd^.next := RefNew;
    outRefEnd := RefNew;
  end;
end;{ InsertElement }

procedure PrintList;
{打印链表所有元素}
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.

这样修改后,CreateList会正确维护尾指针RefEnd,调用InsertElement时outRefEnd指向的是链表的最后一个节点,就能安全地执行outRefEnd^.next := RefNew操作了。

内容的提问来源于stack exchange,提问作者Lucky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:22:48