2013-05-25 507 views
2

我有一個問題,理解指針的行爲設置爲零在帕斯卡。我使用渦輪pascal 7.0。 看來,當我設置兩個指針頭,尾部爲零...他們似乎總是指向未來相同的值,即使他們被分配到不同值。零指針帕斯卡爾

在下面的代碼中,當我註釋掉問題區域並獲得預期結果時。

當我從這兩行刪除註釋 head:= nil; tail:= nil;

當取消引用時,'head'指針似乎總是將'tail'指針的值賦予給它。任何見解提供將不勝感激。

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 
. 
+0

如果您的'更新的解決方案'仍然有錯誤,然後描述它們。否則將其作爲自我回答發佈。 –

+0

對不起,我剛剛看到這個回覆。我會等待進一步的答覆,然後做你的建議。 –

回答

1

有幾件奇怪的事情。

您將數據加載到堆棧(node1)上分配一個記錄,該記錄將在過程退出時執行,然後將其內容(不是引用/指針)深入複製到分配給頭尾的記錄中(使用新的) 。

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

在這一點上,你有節點1的內容,節點1的三個副本,頭2和尾^

隨着節點2你犯同樣的錯誤。 (head^.NodePtr ^:= node2)

您可以通過簡單地分配點來指定點,例如,

 head:=tail; 

和接入領域的直接太

 head^.field:=something 

如果頭點的東西理智。

該構建:

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

本質上是一個內存泄漏。您將記錄空間分配給nodeptr,但是立即將NIL分配給它,而不會引用剛剛分配的記錄。

提示:首先用紙盒(表示記錄)和箭頭(表示指針)在紙上制定算法。

+0

謝謝你的深入回覆。有很多事情我不知道。我會弄清楚我正在嘗試做什麼的確切細節。 –

+0

所做的更改:不再需要過程調用 –

+0

您仍然將堆棧上的記錄分配給指針。在動態數據結構的情況下是錯誤的,因爲它們在函數退出時無效。 –

1

修訂1-移除局部變量節點1和節點

集尾巴「下一個節點」指針爲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 
.