somePointer[n]
BlitzMax Forums/BlitzMax Programming/somePointer[n]
| ||
| What is the difference between somePointer[0] and somePointer[1]? here is an example that doesnt perform properly when somePointer[0] is used within an object, but works properly when outside of the object. Look at the comment inside the object and change the [0] to [1] and it works. Why? Strict Type TGem Field id:Int EndType Type TQue Global gemPtrList:TList Method addPtr(n:TGem) If gemPtrList = Null Then gemPtrList = New TList Local p:TGemPtrList = New TGemPtrList p.gemPtr = Varptr n gemPtrList.AddLast p End Method Method showQue() For Local n:TGemPtrList = EachIn gemPtrList '****************************************************** '******* change n.gemPtr[0] to n.gemPtr[1] and it works Print n.gemPtr[0].toString() Next End Method EndType Type TGemPtrList Field gemPtr:TGem Ptr EndType Global gem:TGem Global que:TQue For Local i = 0 To 10 gem:TGem =New TGem gem.id = i que:TQue = New TQue que.addPtr(gem) Next Print "----------------outside loop" For Local n:TGemPtrList = EachIn que.gemPtrList Print n.gemPtr[0].toString() Next Print "----------------inside loop" que.showQue() |
| ||
| There are quite a few things about the code you are using which don't make sense - so I cannot help there but these are the basics of BMAX pointers: 1. A pointer is simply a variable containing the memory address of some data. 2. To access the value stored at that address, use somePointer[0]. 3. To access the next value after that address, use somePointer[1]. To access the value after that, use somePointer[2], and so on. For example, if somePointer was an Integer pointer (Int Ptr), and it pointed to memory location 100, somePointer[0] would get the integer stored at memory location 100, somePointer[1] would get the integer stored at 104 (Int = 4 bytes long), somePointer[2] would get the integer stored at 108. 4. There is no real need to get pointers to BlitzMAX objects (including Strings and Arrays), since they are already passed as references to functions and methods (that is, when you call a function and pass an object as an argument, BlitzMAX internally just passes the address of the object, not the whole object itself) |
| ||
| Thanks for the input Robert. The reason I need the pointer is a bit complicated to explain. Just curious, what parts of the code doesn't make sense? I'm struggling a bit with good OOP implementation in blitzmax so any advice/criticism would help. Thanks. |
| ||
| Robert did a pretty good job explaining the pointer access stuff so i wont explain that... im pretty confused as well by your code :) sometimes points dont come across very well when paring your code down for help :) in any case, is your goal to store pointers to gems in the que and display their ID? the example code you have is showing the acutal pointer values for me. here are a few things i see right off the bat: Type TGemPtrList Field gemPtr:TGem Ptr EndType not sure i see a need for this? maybe because you cant store a Ptr into a list? you should probably just store the TGem instead of the Ptr, then pass Varptr() of the gem field to whatever requires a pointer. also: For Local i = 0 To 10 gem:TGem =New TGem gem.id = i que:TQue = New TQue que.addPtr(gem) Next arent you recreating the TQue each time through the loop? i would think you probably want to create que one time before the loop and then add to it each time through the loop. and finally, i think why you are getting the results you are getting is because storing Ptr does _not_ increment the internal reference counter. each time through the for loop you are overwriting gem with a new gem. this actually sets the old gem to null and because varptr doesnt increment the internal counter, that gem is marked for deletion by the garbage collector. i think you are getting whatever is at that memory location when you do the reference. so, a modified version of what you have would be:
Framework BRL.Basic
Strict
Type TGem
Field id:Int
' added method to show when being deleted
Method Delete()
Print("deleting: "+id)
EndMethod
EndType
Type TQue
Global gemPtrList:TList
Method addPtr(n:TGem)
If gemPtrList = Null Then gemPtrList = New TList
Local p:TGemPtrList = New TGemPtrList
' changed to store gem reference which does increment the ref counter
p.gem=n
gemPtrList.AddLast p
End Method
Method showQue()
Local n:TGemPtrList
For n = EachIn gemPtrList
Print n.gem.id
Next
End Method
EndType
Type TGemPtrList
Field gem:TGem
' method to get the gem ptr
Method getGemPtr:TGem Ptr()
Return Varptr(gem)
EndMethod
EndType
Global gem:TGem
Global que:TQue
' moved this to outside of loop
que:TQue = New TQue
For Local i = 0 To 3
gem:TGem =New TGem
gem.id = i
que.addPtr(gem)
Next
FlushMem
Print "----------------outside loop direct"
For Local n:TGemPtrList = EachIn que.gemPtrList
Print n.gem.id
Next
Print "----------------inside loop direct"
que.showQue()
Print "----------------outside loop pointer using method"
For Local n:TGemPtrList = EachIn que.gemPtrList
Print n.getGemPtr()[0].id
Next
Print "----------------outside loop pointer direct"
Local gemtemp:TGem Ptr
For Local n:TGemPtrList = EachIn que.gemPtrList
gemtemp=Varptr(n.gem)
Print gemtemp[0].id
Next
hope this helps a bit. im not the best explainer :) |
| ||
| Gman thanks for the good example, it has helped a lot :) You did a fine job explaining. I should have posted a watered down example as you suggested instead of an almost direct excerpt from the code. |