Page 1 of 1
ChangeCurrentElement()
Posted: Sat Aug 03, 2019 11:39 am
by Little John
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???)
Re: ChangeCurrentElement()
Posted: Sat Aug 03, 2019 12:44 pm
by freak
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.
Re: ChangeCurrentElement()
Posted: Sat Aug 03, 2019 12:46 pm
by chi
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???)
Re: ChangeCurrentElement()
Posted: Sat Aug 03, 2019 2:13 pm
by STARGÅTE
@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.
Re: ChangeCurrentElement()
Posted: Sat Aug 03, 2019 2:27 pm
by mk-soft
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
Re: ChangeCurrentElement()
Posted: Sat Aug 03, 2019 2:33 pm
by Little John
@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.