Just starting out? Need help? Post your questions and find answers here.
Little John
Addict
Posts: 4519 Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany
Post
by Little John » Sat Aug 03, 2019 11:39 am
In the third-last line of the following code,
ChangeCurrentElement() changes to an element that does not exist anymore!
In the next line,
Debug shows the content of that not-existing element!
Fred, when you are working on
ChangeCurrentElement() anyway for fixing this bug, it probably won't be much additional work to implement
this related wish .
Code: Select all
; PB 5.71 beta 2 (x64) on Windows 10
EnableExplicit
Define *p
NewList lst.i()
AddElement(lst()) : lst() = 12
AddElement(lst()) : lst() = 15
*p = @ lst()
Debug @ lst() ; -> 7998400 in my test
Debug lst() ; -> 15 (as expected)
DeleteElement(lst())
Debug ListSize(lst()) ; -> 1 (as expected)
Debug @ lst() ; -> 7998368 in my test
Debug lst() ; -> 12 (as expected)
ChangeCurrentElement(lst(), *p)
Debug @ lst() ; -> 7998400 in my test (How is that possible???)
Debug lst() ; -> 15 (How is that possible???)
freak
PureBasic Team
Posts: 5929 Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany
Post
by freak » Sat Aug 03, 2019 12:44 pm
The documentation states:
The element must be a pointer to another element which exists in this list.
You called the function with invalid input, hence the behavior is undefined.
No bug.
quidquid Latine dictum sit altum videtur
chi
Addict
Posts: 1028 Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria
Post
by chi » Sat Aug 03, 2019 12:46 pm
Code: Select all
; PB 5.71 beta 2 (x64) on Windows 10
EnableExplicit
Define *p
NewList lst.i()
AddElement(lst()) : lst() = 12
AddElement(lst()) : lst() = 15
*p = @ lst()
Debug @ lst() ; -> 7998400 in my test
Debug lst() ; -> 15 (as expected)
DeleteElement(lst())
Debug ListSize(lst()) ; -> 1 (as expected)
Debug @ lst() ; -> 7998368 in my test
Debug lst() ; -> 12 (as expected)
*p = #Null
ChangeCurrentElement(lst(), *p)
Debug @ lst() ; -> 7998400 in my test (How is that possible???)
Debug lst() ; -> 15 (How is that possible???)
Et cetera is my worst enemy
STARGÅTE
Addict
Posts: 2067 Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:
Post
by STARGÅTE » Sat Aug 03, 2019 2:13 pm
@Little John:
For speed optimization DeleteElement() doesn't delete the memory of the element or its content,
it just changes the links for next and previous element.
For speed optimization ChangeCurrentElement() doesn't check the pointer whether it is valid.
Thats a nice feature of Pure Basic linked List and not a bug.
mk-soft
Always Here
Posts: 5335 Joined: Fri May 12, 2006 6:51 pm
Location: Germany
Post
by mk-soft » Sat Aug 03, 2019 2:27 pm
Make sure the element is still there.
Code: Select all
;-TOP
; List Managment by mk-soft
EnableExplicit
Structure udtMyList
refCount.i
iVal.i
EndStructure
Global MutexMyList = CreateMutex()
Procedure GetListElement(List MyList.udtMyList())
LockMutex(MutexMyList)
MyList()\refCount + 1
UnlockMutex(MutexMyList)
ProcedureReturn @MyList()
EndProcedure
Procedure FreeListElement(List Mylist.udtMyList(), *ppMyList.Integer, Delete = #True)
Protected *pMyList.udtMyList
LockMutex(MutexMyList)
If *ppMyList\i
*pMyList.udtMyList = *ppMyList\i
If *pMyList\refCount > 0
*pMyList\refCount - 1
If *pMyList\refCount = 0 And Delete = #True
If @Mylist() = *pMyList
DeleteElement(Mylist())
Else
PushListPosition(MyList())
ChangeCurrentElement(Mylist(), *pMyList)
DeleteElement(Mylist())
PopListPosition(Mylist())
EndIf
EndIf
EndIf
*ppMyList\i = 0
EndIf
UnlockMutex(MutexMyList)
EndProcedure
Procedure DeleteListElement(List MyList.udtMyList())
LockMutex(MutexMyList)
If MyList()\refCount = 0
DeleteElement(MyList())
EndIf
UnlockMutex(MutexMyList)
EndProcedure
Global NewList MyData.udtMyList()
AddElement(MyData())
MyData()\iVal = 1
AddElement(MyData())
MyData()\iVal = 2
AddElement(MyData())
MyData()\iVal = 3
AddElement(MyData())
MyData()\iVal = 4
SelectElement(MyData(), 2)
Debug "Get Pointer A"
Define *a.udtMyList = GetListElement(MyData())
Debug "Get Pointer B"
Define *b.udtMyList = GetListElement(MyData())
Debug "Get Pointer C"
SelectElement(MyData(), 1)
Define *c.udtMyList = GetListElement(MyData())
ForEach MyData()
Debug "refCount = " + MyData()\refCount + " | Value = " + MyData()\iVal
Next
Debug "Free Pointer A"
FreeListElement(MyData(), @*a)
ForEach MyData()
Debug "refCount = " + MyData()\refCount + " | Value = " + MyData()\iVal
Next
Debug "Free Pointer B"
FreeListElement(MyData(), @*b)
ForEach MyData()
Debug "refCount = " + MyData()\refCount + " | Value = " + MyData()\iVal
Next
Debug "Free all unused ListElements"
ForEach MyData()
DeleteListElement(MyData())
Next
ForEach MyData()
Debug "refCount = " + MyData()\refCount + " | Value = " + MyData()\iVal
Next
Debug "Free Pointer C"
FreeListElement(MyData(), @*c)
ForEach MyData()
Debug "refCount = " + MyData()\refCount + " | Value = " + MyData()\iVal
Next
Little John
Addict
Posts: 4519 Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany
Post
by Little John » Sat Aug 03, 2019 2:33 pm
@STARGÅTE:
Yes, I see now.
I previouly believed that PureBasic would keep internally an inventory of pointers which a valid for a particular list.
As freak explained this is not the case. So I do understand why
ChangeCurrentElement() behaves the way it currently does.