2

我在理解 Pascal 中设置为 nil 的指针的行为时遇到了问题。我正在使用涡轮帕斯卡 7.0。 似乎当我将两个指针 head,tail 设置为 nil 时......它们似乎总是指向未来的相同值,即使它们被分配给不同的值。

在下面的代码中,当我注释掉了问题区域,并得到了预期的结果。

当我从这对行中删除注释时 head:=nil; 尾巴:=无;

在取消引用时,“头”指针似乎总是采用赋予“尾”指针的值。提供的任何见解将不胜感激。

    program LinkedListTest;
type
    ListNodePtr = ^ListNode;
    ListNode = record
        key,cycleLength: integer;
        NodePtr: ListNodePtr;
    end;

{
We have just defined the node of a linked list.
Next we declare our head which is the pointer to the first node
and the tail which points to the last node.
The head helps us find our first node in the list
the tail helps us to keep track of the last node in the list.
Both are simple pointers to a node (in our case ListNodePtr).
}

var
head,tail : ListNodePtr;
node1,node2,node3,node4: ListNode;
count: integer;

{Init the linked list}

procedure InitLinkedList;
Begin
new(head);
new(tail);

(*   **Remove comments from this code to see problems in final output**
head:=nil;
tail:=nil;
*)
node1.key:=10;

new(node1.NodePtr);
node1.NodePtr:=nil;
head^:=node1;
tail^:=node1;
writeln('head key is now: ',head^.key);



node2.key:=20;
new(node2.NodePtr);
node2.NodePtr:=nil;




head^.NodePtr^:=node2;



tail^:=node2;

writeln('head key is now: ',head^.key);
writeln('tail key is now: ',tail^.key);
writeln('node1 key is now: ',node1.key);
writeln('node2 key is now: ',node2.key);
readln;
end;

begin

InitLinkedList;

end
.
4

2 回答 2

1

有几个奇怪的事情。

您将数据加载到堆栈(node1)上分配一条记录,该记录将在过程退出时消失,然后将其内容(不是引用/指针)深度复制到分配给头和尾的记录中(使用新的)。

       head^:=node1;
       tail^:=node1;

此时,您拥有 node1 内容的三个副本,node1、head^ 和 tail^

使用 node2 你会犯同样的错误。(head^.NodePtr^:=node2)

您可以通过简单地分配积分来分配积分,例如

     head:=tail;

并直接访问字段

       head^.field:=something

如果 head 指向理智的东西。

这个构造:

  new(node1.NodePtr);
  node1.NodePtr:=nil;

本质上是内存泄漏。您为记录分配空间给 nodeptr,然后立即为其分配 NIL,不留下对刚刚分配的记录的引用。

提示:首先在纸上用方框(表示记录)和箭头(表示指针)制定你的算法。

于 2013-05-25T11:48:49.267 回答
1

修订版 1- 删除了局部变量 Node1 和 Node2

将尾部“下一个节点”指针设置为 nil

检查列表中 2 个节点的头指向尾

基于答案的更新解决方案

program LinkedListTest;
type
    ListNodePtr = ^ListNode;
    ListNode = record
        key,cycleLength: integer;
        NodePtr: ListNodePtr;
    end;


var
head,tail,tempPtr : ListNodePtr;
count: integer;
pointerIsNil: boolean;
{Init the linked list}


begin

new(head);
new(tail);
new(tempPtr);
tempPtr^.key:=10;
head:=tempPtr;
tail:=tempPtr;
tail^.NodePtr:=nil;
writeln('head key is now: ',head^.key);
writeln('tail key is now: ',tail^.key);
pointerIsNil:=head^.NodePtr = nil;
writeln('Is heads node ptr nil? Answer is: ',pointerIsNil);
new(tempPtr);
tempPtr^.key:=20;
head^.Nodeptr:=tempPtr;
tail:=tempPtr;
writeln('head key is now: ',head^.key);
writeln('tail key is now: ',tail^.key);

pointerIsNil:=head^.NodePtr = nil;
writeln('Is heads node ptr nil? Answer is: ',pointerIsNil);
writeln('Making sure head is linked to the tail ',head^.NodePtr^.key);


readln;


end
.
于 2013-05-26T15:21:02.587 回答