Author |
Topic: Linked Lists (Read 3019 times) |
|
Matt
Developer
member is offline


Gender: 
Posts: 210
|
 |
Re: Linked Lists
« Reply #7 on: Sep 25th, 2014, 7:39pm » |
|
Right. I think I understand the principal of the linked list program in the Wiki example. What I'm trying to do, though - and failing - is to import the records from a data file into a complex structure and then pass them into the linked list. I DIM the structure Detail{} including the member detail.link%, and then DIM Node{} = Detail{}. In the middle of the Wiki example it sets the node.item$ and node.misc to the word$ and index. What I tried to do was to copy the structure by using node{} = detail{} and then setting node.link% to the link pointer this%. However, through investigation, I find that when comparing the values in the first WHILE loop using detail.item$ rather than word$, it seems that the detail.item$ and the returning node.item$ are always the same. When I copy the structure one member at a time, it seems to work, but not by doing a straight copy in this way - yet the data pointers seem to be different.
As I realise, time and time again, understanding the basic principle and putting that into practice are two completely different things. (Or maybe I've just never understood the basic principle.)
If the explanation makes no sence, I appologise.
Matt
|
|
Logged
|
|
|
|
rtr2
Guest
|
 |
Re: Linked Lists
« Reply #8 on: Sep 25th, 2014, 8:17pm » |
|
on Sep 25th, 2014, 7:39pm, Matt wrote:| What I tried to do was to copy the structure by using node{} = detail{} |
|
I wonder if you failed to take note of this warning in the BB4W manual:
"Do not copy structures containing string members; since only the string descriptor is copied, not the string itself, you are likely to confuse BASIC and may even crash it."
http://www.bbcbasic.co.uk/bbcwin/manual/bbcwin2.html#structcopy
Richard.
|
| « Last Edit: Sep 25th, 2014, 8:19pm by rtr2 » |
Logged
|
|
|
|
Matt
Developer
member is offline


Gender: 
Posts: 210
|
 |
Re: Linked Lists
« Reply #9 on: Sep 26th, 2014, 4:06pm » |
|
on Sep 25th, 2014, 8:17pm, g4bau wrote:| I wonder if you failed to take note of this warning in the BB4W manual: |
|
Err... I had forgotten. Taking note and remembering, for me, are two completely seperate things.
Irritatingly, when I'd first started experimenting with linked lists, I'd examined the format of structures and remember thinking about this. However, with all the fiddling around I was doing, it had completely slipped my mind.
I haven't tried adjusting the test program yet, but hopefully it will now work - although, I'll have to transfer the data one member at a time, and ther are a few members.
As you stated before, Jon Ripley's very clever PROC_ClearStruct enables clearing the structure. Is there any way, then, to quickly copy an entire structure - including string variables - without causing a problem? If not, is it because of the way BB4W adjusts the length/location of the string allocation, depending on its size. Would this cause a problem in a direct copy? Only curious.
Matt
|
|
Logged
|
|
|
|
Matt
Developer
member is offline


Gender: 
Posts: 210
|
 |
Re: Linked Lists
« Reply #10 on: Sep 26th, 2014, 7:32pm » |
|
Hi,
I'm sorry. This is so frustrating. I get the impression there is something glaringly obvious that I'm not seeing. Here's a massivly cut down version of the testing that I'm doing. Can you tell me what on earth I'm missing?
As you can see, I've tried putting in printed items to see if I can work out what's going on. I've also tried running the 'Trace' and 'List all variables', and running step by step. I'm just missing what's wrong.
(The letters 'C', 'A', 'B', 'D' are specifically in that order to allow the first to be inserted in the first position, the second to be inserted into first infront of that one, the third to be inserted between the two, and the fourth to be inserted in at the end - all the different combinations of inserting I could think of.)
Code: File$ = @usr$ + "TestFile.dat"
DIM Detail{ Category{ Main$ }, Link{ Next% } }
DIM Node{} = Detail{}
DIM ListPtr{ Details{ Used%, Free% } }
PROC_CREATE_DATA_FILE
F% = OPENIN(File$)
WHILE NOT EOF#F%
PROC_RECORD_INPUT(F%, Detail{})
PRINT '"NEW DETAIL VALUE = """; Detail.Category.Main$; """"
PrevPtr% = 0
ThisPtr% = ListPtr.Details.Used%
C% = 0
WHILE (ThisPtr% <> 0) AND (Detail.Category.Main$ > FN_GET_ITEM(Node{}, ThisPtr%))
C% += 1 : PRINT "LOOP = ";C% : IF C% > 4 THEN STOP
PrevPtr% = ThisPtr%
ThisPtr% = Node.Link.Next%
ENDWHILE
NewPtr% = FN_NEW_NODE(Node{})
PROC_COPY_STRUCTURE(Detail{}, Node{})
Node.Link.Next% = ThisPtr%
PRINT "ThisPtr% = ";ThisPtr%
IF PrevPtr% THEN
PROC_SET_LINK(Node{}, PrevPtr%, NewPtr%)
ELSE
ListPtr.Details.Used% = NewPtr%
ENDIF
PRINT "ListPtr.Details.Used% = "; ListPtr.Details.Used%
ENDWHILE
CLOSE#F%
END
DEF PROC_SET_LINK(n{}, n%, l%)
!(^n{}+4) = n%
n.Link.Next% = l%
ENDPROC
DEF FN_NEW_NODE(RETURN n{})
LOCAL P%
DIM P% DIM(n{})-1
!(^n{}+4) = P%
PRINT "NEW NODE PTR = "; P%
= P%
DEF FN_GET_ITEM(n{}, P%)
IF P% = 0 THEN = ""
!(^n{}+4) = P%
PRINT "NODE VALUE = """; n.Category.Main$; """"
= n.Category.Main$
DEF PROC_COPY_STRUCTURE(from{}, to{})
to.Category.Main$ = from.Category.Main$
ENDPROC
DEF PROC_RECORD_INPUT(F%, rec{})
LOCAL text$, key$, info$
PROC_ClearStruct(rec{})
REPEAT INPUT#F%, text$ : UNTIL INSTR(text$, "Start Record") > 0 OR EOF#F%
INPUT#F%, text$
IF EOF#F% THEN = FALSE
WHILE INSTR(text$, "End Record") = 0 AND NOT EOF#F%
IF ASC(text$) = 10 THEN text$ = MID$(text$, 2)
key$ = LEFT$(text$, INSTR(text$, "="))
info$ = MID$(text$, INSTR(text$, "=") + 1)
CASE key$ OF
WHEN "Category Main=" : rec.Category.Main$ = info$
ENDCASE
INPUT#F%, text$
ENDWHILE
ENDPROC
DEF PROC_ClearStruct(S{})
LOCAL E{}, F{}
DIM E{} = S{}, F{} = S{}
E{} = S{} : S{} = F{}
ENDPROC
DEF PROC_CREATE_DATA_FILE
LOCAL F%
RESTORE +1
DATA C, A, B, D
F% = OPENOUT(File$)
FOR I% = 0 TO 3
READ Detail.Category.Main$
PRINT#F%, CHR$10 + "[--Start Record--]"
PRINT#F%, CHR$10 + "Category Main=" + Detail.Category.Main$
PRINT#F%, CHR$10 + "[--End Record--]"
NEXT
CLOSE#F%
ENDPROC
Sorry to be a pain.
Matt
|
|
Logged
|
|
|
|
rtr2
Guest
|
 |
Re: Linked Lists
« Reply #11 on: Sep 26th, 2014, 9:02pm » |
|
on Sep 26th, 2014, 4:06pm, Matt wrote:| Is there any way, then, to quickly copy an entire structure - including string variables - without causing a problem? |
|
It rather depends on what the contents of the structure are. In an extreme case, when there is only one string member and all the others are numeric, you could write a relatively efficient copy routine as follows:
Code: temp$ = ""
SWAP temp$, src.member$
dst{} = src{}
dst.member$ = temp$
SWAP temp$, src.member$ This initially swaps out the string member and replaces it with an empty string, creating a structure which is safe to copy. The copy then takes place, and the string member of the destination structure is copied from the temporary variable. Finally the string is swapped back into the source structure.
As a procedure this might be:
Code: DEF PROCcopystructwithstring(dst{}, src{})
LOCAL temp$
SWAP temp$, src.member$
dst{} = src{}
dst.member$ = temp$
SWAP temp$, src.member$
ENDPROC Richard.
|
| « Last Edit: Sep 26th, 2014, 9:18pm by rtr2 » |
Logged
|
|
|
|
rtr2
Guest
|
 |
Re: Linked Lists
« Reply #12 on: Sep 27th, 2014, 02:36am » |
|
on Sep 26th, 2014, 7:32pm, Matt wrote:| I get the impression there is something glaringly obvious that I'm not seeing. |
|
I wouldn't say "glaringly obvious", although it would have been had you printed out the value of ThisPtr% inside your WHILE loop (it never changes)! You are missing a RETURN:
Code: DEF FN_GET_ITEM(RETURN n{}, P%) Richard.
|
|
Logged
|
|
|
|
|