Linked list modeling in Free Pascal - pointers

I am currently solving the problem of creating a singly linked list using pointers in Free Pascal. The task:
Write a program that reads integers from the standard input stream until the "end of file" situation occurs, after which it prints all the entered numbers TWICE in the order in which they were entered. The quantity of numbers is not known in advance, explicit restrictions on this number are prohibited.
In my program, the list is built in the wrong order. How to build the correct sequence?
program InputStreamNumbers;
type
itemptr = ^item;
item = record
data: Integer;
next: itemptr;
end;
var
first, tmp: itemptr;
n: Integer;
begin
first := nil; { make the list properly empty! }
while not SeekEof do { number reading loop }
begin
read(n);
new(tmp); { created }
tmp^.data := n; { fill out}
tmp^.next := first;
first := tmp; { include in the list}
end;
tmp := first; { go through the list from beginning to end }
while tmp <> nil do
begin
writeln(tmp^.data);
tmp := tmp^.next; { move to the next element}
end;
end.

When you add nodes to the list, you create a new node named tmp and assign its data. That's correct. But there is an error in how you add new items to the list. The error is in
tmp^.next := first; // this creates the backwards linkage
first := tmp;
If you can (assuming it's not against your task), add one variable more
last: itemptr;
which, as the name says, refers to the last item in the list.
The purpose is to have direct access to the end of the list, to make it easier to add items. Otherwise you would need to traverse the list from the beginning until you find the last item ( who's item.next is nil).
The list should end up like this:
first last
| |
v v
item.next -> item.next -> item.next -> item.next = nil
.data .data .data .data
I leave the implementation for you to do. But if it helps, initially first and last are nil. After one item is created, both first and last point to that one item. After a second item is created, first still points to the first created, but last points to the second ... and so on.

Related

Pascal linked list to linked list does not work

These are two linked lists that I've made,for a school project...
I want the first list to be called from the second,I have done that and at the compile time everything is ok. When I run it it says :
Project (myProject) raised exception class 'External: SIGSEGV'.
At address 40D32D
Here is my code:
list2=^ptr;
ptr=record
vlera:integer;
pozicioni:integer;
end;
type
list=^pointer;
pointer=record
rreshti:list2;
end;
var
a:array[1..7] of list;
i:integer;
kjovlere:list2;
begin
for i:=1 to 7 do begin
a[i]:=#kjovlere;
write('Give the pozition for the row:',i,' : ');
read(a[i]^.rreshti^.pozicioni);
write ('give the value for this poziton :');
read(a[i]^.rreshti^.vlera);
writeln;
end;
end.
And the error is at the for loop,at the read(a[i]^.rreshti^.pozicioni);
I would be very thankful if anyone explains me or gives me any suggestion :)
The provided source code shows at least two misunderstandings about pointer management in Pascal.
Main Problem - To assign data, a record type shall be allocated before.
This problem is referring to the lines read(a[i]^.rreshti^.pozicioni); and read(a[i]^.rreshti^.vlera);.
Both a[i] and rreshti are declared as pointer type (list=^pointer; & list2=^ptr;) and shall be allocated to a record structure before assigning data.
Step1: allocate the a[i] pointer in the loop.
new(a[i]);
Step2: allocate the a[i]^.rreshti pointer in the loop.
new(a[i]^.rreshti);
Strange Problem - Assign a pointer to a record type shall respect the destination type.
This problem is referring to the line a[i]:=#kjovlere;.
The a[i] is a list which is list=^pointer; and not list2 (list2=^ptr;) as declared for kjovlere:list2;.
Solution is: remove that line a[i]:=#kjovlere;.
Solution:
begin
for i:=1 to 7 do begin
(* a[i]:=#kjovlere; to be removed *)
new(a[i]);
new(a[i]^.rreshti);
write('Give the pozition for the row:',i,' : ');
read(a[i]^.rreshti^.pozicioni);
write ('give the value for this poziton :');
read(a[i]^.rreshti^.vlera);
writeln;
end;
end.

Linked List: Copy List Using Recursive

I am new to Linked List. I am trying to write a CopyList() code that can copy a linked list to a new list. There's a unique version using recursive and I don't really understand:
struct node
{
int data;
struct node *next;
};
struct node* CopyList(struct node* head) {
struct node* current = head;
if (current == NULL) return NULL;
else {
struct node* newList = malloc(sizeof(struct node));
newList->data = current->data;
newList->next = CopyList(current->next); // recur for the rest
return(newList);
}
}
My trouble of understanding is the line newList->next = CopyList(current->next);
So how does this work for copying and why?
Lets take an example. If you simply put the current->next in newList->next
i.e
newList->next = current->next. Then it will point to the next node of old list only. Not to the next node of new list.
So to make a different list (Copy list). You separately have to make a new node and return it to point to next of previous node.
This is the magical recursive statement.
newList->next = CopyList(current->next);
For each recursive step, this will delegate the task of creating remaining linked list, to the next recursive call.
For example: List is getting created from right to left.
CopyList (1->2->3->4->5)
|
|---------1-> CopyList (2->3->4->5)
|
|---------2-> CopyList (3->4->5)
|
|---------3-> CopyList (4->5)
|
|---------4-> CopyList (5)
|
|---------5-> CopyList (NULL)
Returns 5
Returns 4->5->NULL
Returns 3->4->5->NULL
Returns 2->3->4->5->NULL
Returns 1->2->3->4->5->NULL
As per wiki
A simple base case (or cases)—a terminating scenario that does not use recursion to produce an answer.
A set of rules that reduce all other cases toward the base case.
In your case, terminating scenario is if list reaches the end, just return null and a new node is created at every step that leads the list to the base scenario.
This is the recursion step. The previous two commands create a new node and copy the head of the current list to that object. Now, instead of iterating (looping) through the rest of the list, we call CopyList to copy the remainder of the list -- everything except the head node that we just copied.
CopyList returns a copy of that remainder, which we simply append to the copy of the head node ... and we're done.

Golang Reusing Memory Address Copying from slice?

I was hitting an issue in a project I'm working on. I found a way around it, but I wasn't sure why my solution worked. I'm hoping that someone more experience with how Go pointers work could help me.
I have a Model interface and a Region struct that implements the interface. The Model interface is implemented on the pointer of the Region struct. I also have a Regions collection which is a slice of Region objects. I have a method that can turn a Regions object into a []Model:
// Regions is the collection of the Region model
type Regions []Region
// Returns the model collection as a list of models
func (coll *Regions) ToModelList() []Model {
output := make([]Model, len(*coll))
for idx, item := range *coll {
output[idx] = &item
}
return output
}
When I run this code, I end up with the first pointer to the Region outputted multiple times. So, if the Regions collection has two distinct items, I will get the same address duplicated twice. When I print the variables before I set them in the slice, they have the proper data.
I messed with it a little bit, thinking Go might be reusing the memory address between loops. This solution is currently working for me in my tests:
// Returns the model collection as a list of models
func (coll *Regions) ToModelList() []Model {
output := make([]Model, len(*coll))
for idx, _ := range *coll {
i := (*coll)[idx]
output[idx] = &i
}
return output
}
This gives the expected output of two distinct addresses in the output slice.
This honestly seems like a bug with the range function reusing the same memory address between runs, but I always assume I'm missing something in cases like this.
I hope I explained this well enough for you. I'm surprised that the original solution did not work.
Thanks!
In your first (non working) example item is the loop variable. Its address is not changing, only its value. That's why you get the same address in output idx times.
Run this code to see the mechanics in action;
func main() {
coll := []int{5, 10, 15}
for i, v := range coll {
fmt.Printf("This one is always the same; %v\n", &v)
fmt.Println("This one is 4 bytes larger each iteration; %v\n", &coll[i])
}
}
There is just one item variable for the entire loop, which is assigned the corresponding value during each iteration of the loop. You do not get a new item variable in each iteration. So you are just repeatedly taking the address of the same variable, which will of course be the same.
On the other hand, if you declared a local variable inside the loop, it will be a new variable in each iteration, and the addresses will be different:
for idx, item := range *coll {
temp := item
output[idx] = &temp
}

Is it safe to remove selected keys from map within a range loop?

How can one remove selected keys from a map?
Is it safe to combine delete() with range, as in the code below?
package main
import "fmt"
type Info struct {
value string
}
func main() {
table := make(map[string]*Info)
for i := 0; i < 10; i++ {
str := fmt.Sprintf("%v", i)
table[str] = &Info{str}
}
for key, value := range table {
fmt.Printf("deleting %v=>%v\n", key, value.value)
delete(table, key)
}
}
https://play.golang.org/p/u1vufvEjSw
This is safe! You can also find a similar sample in Effective Go:
for key := range m {
if key.expired() {
delete(m, key)
}
}
And the language specification:
The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next. If map entries that have not yet been reached are removed during iteration, the corresponding iteration values will not be produced. If map entries are created during iteration, that entry may be produced during the iteration or may be skipped. The choice may vary for each entry created and from one iteration to the next. If the map is nil, the number of iterations is 0.
Sebastian's answer is accurate, but I wanted to know why it was safe, so I did some digging into the Map source code. It looks like on a call to delete(k, v), it basically just sets a flag (as well as changing the count value) instead of actually deleting the value:
b->tophash[i] = Empty;
(Empty is a constant for the value 0)
What the map appears to actually be doing is allocating a set number of buckets depending on the size of the map, which grows as you perform inserts at the rate of 2^B (from this source code):
byte *buckets; // array of 2^B Buckets. may be nil if count==0.
So there are almost always more buckets allocated than you're using, and when you do a range over the map, it checks that tophash value of each bucket in that 2^B to see if it can skip over it.
To summarize, the delete within a range is safe because the data is technically still there, but when it checks the tophash it sees that it can just skip over it and not include it in whatever range operation you're performing. The source code even includes a TODO:
// TODO: consolidate buckets if they are mostly empty
// can only consolidate if there are no live iterators at this size.
This explains why using the delete(k,v) function doesn't actually free up memory, just removes it from the list of buckets you're allowed to access. If you want to free up the actual memory you'll need to make the entire map unreachable so that garbage collection will step in. You can do this using a line like
map = nil
I was wondering if a memory leak could happen. So I wrote a test program:
package main
import (
log "github.com/Sirupsen/logrus"
"os/signal"
"os"
"math/rand"
"time"
)
func main() {
log.Info("=== START ===")
defer func() { log.Info("=== DONE ===") }()
go func() {
m := make(map[string]string)
for {
k := GenerateRandStr(1024)
m[k] = GenerateRandStr(1024*1024)
for k2, _ := range m {
delete(m, k2)
break
}
}
}()
osSignals := make(chan os.Signal, 1)
signal.Notify(osSignals, os.Interrupt)
for {
select {
case <-osSignals:
log.Info("Recieved ^C command. Exit")
return
}
}
}
func GenerateRandStr(n int) string {
rand.Seed(time.Now().UnixNano())
const letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand.Int63() % int64(len(letterBytes))]
}
return string(b)
}
Looks like GC do frees the memory. So it's okay.
In short, yes. See previous answers.
And also this, from here:
ianlancetaylor commented on Feb 18, 2015
I think the key to understanding this is to realize that while executing the body of a for/range statement, there is no current iteration. There is a set of values that have been seen, and a set of values that have not been seen. While executing the body, one of the key/value pairs that has been seen--the most recent pair--was assigned to the variable(s) of the range statement. There is nothing special about that key/value pair, it's just one of the ones that has already been seen during the iteration.
The question he's answering is about modifying map elements in place during a range operation, which is why he mentions the "current iteration". But it's also relevant here: you can delete keys during a range, and that just means that you won't see them later on in the range (and if you already saw them, that's okay).

nil pointer in Pascal

I have a problem understanding the behavior of pointers set to nil in Pascal. I am using turbo pascal 7.0.
It seems that when I set two pointers head,tail to nil...they always seem to point to the same value in the future, even if they are assigned to different values.
In the code below, when I've commented out the problem area, and get the expected results.
When I remove comments from this pair of lines
head:=nil;
tail:=nil;
The 'head' pointer always seems to take the value given to the 'tail' pointer when de-referenced. Any insight provided will be appreciated.
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
.
There are several strange things.
You load data into allocate a record on the stack (node1), which will be gone on procedure exit, and then deep copy its contents (not references/pointers) into the records allocated to head and tail (using new).
head^:=node1;
tail^:=node1;
At that point you have three copies of node1's content, node1, head^ and tail^
With node2 you make the same mistake. ( head^.NodePtr^:=node2)
You can assign the points by simply assigning them, e.g.
head:=tail;
and access fields directly too
head^.field:=something
if head points to something sane.
This construct:
new(node1.NodePtr);
node1.NodePtr:=nil;
is essentially a memory leak. You allocate space for a record to nodeptr, but then immediately assign NIL to it, leaving no reference to the just allocated record.
HINT: work out your algorithm on paper with boxes (to signify records) and arrows (to signify pointers) first.
Revision 1- Removed local variables Node1 and Node2
Set tail 'next node' pointer to nil
check that head points to tail for 2 nodes in the list
UPDATED SOLUTION BASED ON ANSWERS
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
.

Resources