Pascal单向链表实现问题:空指针赋值与运行时错误216排查
解决Pascal单向链表的构建与运行时错误问题
看起来你在构建单向链表时混淆了指针操作和record变量的使用,这直接导致了运行时错误和链表节点无法正确链接的问题。我来帮你拆解核心问题,并给出修正后的代码:
你的代码里的关键错误点
- 错误的初始化逻辑:你在
InitLists已经把head和tail设为nil后,又执行了new(head); new(tail);,这会让head和tail指向两个完全独立的空节点,直接破坏了链表头尾的关联。 - 混淆指针与record变量:你用全局的
node(一个栈上的record变量)来构建节点,然后通过head^ := node、tail^.next^ := node这种方式复制record值,这不是链表的正确构建逻辑——链表的每个节点都应该是动态分配的指针,通过指针地址来链接,而不是复制record内容。 - 错误的节点链接方式:比如你试图给
tail^.next^赋值,这是在修改tail^.next指向的节点的内容,而不是让tail^.next指向一个新的节点指针,这会导致指针指向混乱,触发运行时错误216(访问无效内存)。 - 不鲁棒的打印逻辑:用固定次数的
for循环遍历链表,如果链表构建错误,很容易访问到错误的节点或nil指针。
修正后的完整代码
Program test; type TNodePtr = ^TNode; TNode = record number: Integer; next: TNodePtr; end; var head, tail, temp : TNodePtr; i : INTEGER; procedure InitLists; begin head := nil; tail := nil; end; // 封装添加节点的函数,让逻辑更清晰 procedure AddNode(const num: Integer); var newNode: TNodePtr; begin new(newNode); // 动态分配新节点的内存 newNode^.number := num; newNode^.next := nil; // 新节点默认是尾节点,next设为nil if head = nil then begin // 链表为空时,头和尾都指向新节点 head := newNode; tail := newNode; end else begin // 链表不为空时,把新节点链接到尾部,更新tail tail^.next := newNode; tail := newNode; end; end; begin // 初始化链表 InitLists; // 添加节点 AddNode(1); AddNode(2); AddNode(3); AddNode(4); // 打印链表:用while循环遍历,直到temp为nil writeln('链表内容:'); temp := head; while temp <> nil do begin writeln(temp^.number); temp := temp^.next; end; end.
代码说明
- 初始化:
InitLists只需要把head和tail设为nil,不需要额外new,因为空链表本来就没有节点。 - 添加节点:封装了
AddNode函数,每次添加时动态分配新的TNodePtr,设置节点值和next为nil,然后根据链表是否为空,把新节点链接到正确的位置,并更新tail指针。 - 遍历打印:用
while temp <> nil的方式遍历,不管链表有多少节点,都能安全遍历到最后一个节点,避免固定次数循环的局限性。
这样修改后,你之前遇到的运行时错误216会消失,而且最后一个节点也能正常打印出来。
内容的提问来源于stack exchange,提问作者from_pluto
相关产品推荐
相关产品推荐

