Page 1 of 1

How can I get the pointer to a linked list itself?

Posted: Wed May 16, 2007 7:58 pm
by IceSoft
How can I get the pointer to a linked list itself?

Thanks for help.

Posted: Wed May 16, 2007 8:31 pm
by Inf0Byt3
Try @LinkedListName :)

E.g:

Code: Select all

NewList MyList.s()
AddElement(MyList())
MyList() = "Test"
*PointerToList = @MyList()
Debug *PointerToList
I am not sure that this is the pointer to the list itself or the element though :/.

Posted: Wed May 16, 2007 8:39 pm
by IceSoft
Inf0Byt3 wrote:Try @LinkedListName :)

E.g:

Code: Select all

NewList MyList.s()
AddElement(MyList())
MyList() = "Test"
*PointerToList = @MyList()
Debug *PointerToList
I am not sure that this is the pointer to the list itself or the element though :/.
It is only the first element...not the pointer to the list

Posted: Wed May 16, 2007 9:00 pm
by Trond
A linked list needs a quad (unless you store the pointer to the quad). When I wrote my dynamic linked list code I used asm to get it.

Posted: Thu May 17, 2007 8:15 am
by IceSoft
Hope we get a native solution with the next PB version (4.10).

Posted: Thu May 17, 2007 1:29 pm
by bembulak
If

Code: Select all

*PointerToList = @MyList() 
is the the pointer to the first element, how to get through the elements? Is it possible to cycle trough with pointers?

Posted: Thu May 17, 2007 1:59 pm
by Dare
Hi Icesoft. Is this what you're asking?

Code: Select all

Structure checkitout
  aLong.l
  aString.s
EndStructure

NewList c.checkitout()

AddElement(c())
c()\aLong=$FFFFFFFF
c()\aString="ABC"

AddElement(c())
c()\aLong=12
c()\aString="DEF"

addy=@c()
Debug addy

Debug "=== FIRST ELEMENT INFORMATION"
FirstElement(c())
addy=@c()
Debug "This may be the start of first element and the list: "+Str(addy-8)
Debug "This may be pointer to the PREV element: "+Str(PeekL(addy-4))+" (should be 0)"
Debug "This may be pointer to the NEXT element: "+Str(PeekL(addy-8))
Debug "This may be the addy of the first element: "+Str(addy)
Debug "This should be -1 if so "+Str(PeekL(addy))
Debug "This should be the address of the address of the string: "+Str(PeekL(addy+4))
Debug "This should be the string: "+PeekS(PeekL(addy+4))+ "(Should be ABC)"
Debug "==="
NextElement(c())
addy=@c()
Debug "This may be the start of current element (not the list): "+Str(addy-8)+" (should be same as NEXT in above group)"
Debug "This may be pointer to the PREV element: "+Str(PeekL(addy-4))
Debug "This may be pointer to the NEXT element: "+Str(PeekL(addy-8))+" (should be 0)"
Debug "This may be the addy of the first element: "+Str(addy)
Debug "This should be 12 if so "+Str(PeekL(addy))
Debug "This should be the address of the address of the string: "+Str(PeekL(addy+4))
Debug "This should be the string: "+PeekS(PeekL(addy+4))+ "(Should be DEF)"
Debug "==="
It appears address of first element - 8 is also address of linked list and that the 8 bytes preceding each element are the pointers.

Hope I am answering your question and didn't miss the point.

Also not sure how stable it would be to use this as am not sure how often addresses would change. Probably just on element add/remove but ..... :)

Edit:

Peeking word and long prior to first element -8 doesn't provide any info that makes sense to me (eg, element counts) so if there is other info stored perhaps it is in a control table tucked away somewhere.

Posted: Thu May 17, 2007 2:15 pm
by Trond
bembulak wrote:If

Code: Select all

*PointerToList = @MyList() 
is the the pointer to the first element, how to get through the elements? Is it possible to cycle trough with pointers?

Code: Select all

Structure Element
  *Next.Element
  *Previous.Element
  UserData.b[0]
EndStructure

NewList A()
For I = 0 To 20
  AddElement(A())
  A() = I
Next

*Element.Element = FirstElement(A())

While *Element\Next
  Debug PeekL(@*Element\UserData[0])
  *Element = *Element\Next
Wend

Posted: Thu May 17, 2007 2:45 pm
by Demivec
@Trond: you need a small correction to your code to also show the last element in the list.

Code: Select all

Structure Element
  *Next.Element
  *Previous.Element
  UserData.b[0]
EndStructure

NewList A()
For I = 0 To 20
  AddElement(A())
  A() = I
Next

*Element.Element = FirstElement(A())

Debug PeekL(@*Element\UserData[0])
While *Element\Next
  *Element = *Element\Next
  Debug PeekL(@*Element\UserData[0])
Wend

Posted: Thu May 17, 2007 3:18 pm
by Trond
It crashes if the list is empty.

Code: Select all

Structure Element 
  *Next.Element 
  *Previous.Element 
  UserData.b[0] 
EndStructure 

NewList A() 
For I = 0 To 20 
  AddElement(A()) 
  A() = I 
Next 

*Element.Element = FirstElement(A()) 

If *Element
  While *Element\Next
    Debug PeekL(@*Element\UserData[0])
    *Element = *Element\Next
  Wend
  Debug PeekL(@*Element\UserData[0])
EndIf

Posted: Thu May 17, 2007 4:46 pm
by MrMat
This is a hack! It uses ResetList to get the address of the list header.

Code: Select all

Structure liststructure
    *first    ; pointer to first element
    *last     ; pointer to last element
    size.l    ; size in bytes of each element
    count.l   ; elements in list
    current.l ; -1 or 0 = unknown, 1 = at first element, 2 = second, etc.
EndStructure

Structure elementstructure
    *next.elementstructure
    *prev.elementstructure
    stuff.b[0]
EndStructure

Procedure DebugList(*list.liststructure)
    ; Output list header information
    text.s = "Debug list: " + Str(*list)
    text + " *first: " + Str(*list\first)
    text + " *last: " + Str(*list\last)
    text + " element size: " + Str(*list\size)
    text + " count: " + Str(*list\count)
    text + " current: " + Str(*list\current)
    Debug(text)

    ; Output the index and address of each element
    *element.elementstructure = *list\first
    count.l = 0
    While *element <> 0
        text = "Element no: " + Str(count)
        text + " Address: " + Str(*element)
        Debug(text)
        *element = *element\Next
        count + 1
    Wend
    Debug("")
EndProcedure

NewList mylist.l()
*list = ResetList(mylist())

Debug("Empty list")
DebugList(*list)

Debug("Add element")
AddElement(mylist())
DebugList(*list)

Debug("Add element")
AddElement(mylist())
DebugList(*list)

Debug("Add element")
AddElement(mylist())
DebugList(*list)

Debug("Select second")
SelectElement(mylist(), 1)
*elem = @mylist()
DebugList(*list)

Debug("Reset list")
ResetList(mylist())
DebugList(*list)

Debug("Change to second")
ChangeCurrentElement(mylist(), *elem)
DebugList(*list)

Debug("Delete element")
DeleteElement(mylist())
DebugList(*list)

Debug("Clear list")
ClearList(mylist())
DebugList(*list)
It may not work in the current release let alone any future releases so i take no responsibility if it doesn't work or breaks in the future! :lol:

Posted: Thu May 17, 2007 9:12 pm
by IceSoft
This is implemented in PB <=4.02:
You get a new 'Object'

Code: Select all

NewList list.Point()
AddElement(list())
list()\x = 10
foreach list()
...
next
This is the new syntax example:
(Hope we get such a new feature in PB 4.10)
And here you get the pointer to the 'empty' object

Code: Select all

*addr()\Point = NewList @list.Point()
AddElement(*addr())
*addr()\x = 10
foreach *addr()
...
next