somePointer[n]

BlitzMax Forums/BlitzMax Programming/somePointer[n]

gellyware(Posted 2005) [#1]
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()



Robert(Posted 2005) [#2]
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)


gellyware(Posted 2005) [#3]
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.


gman(Posted 2005) [#4]
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 :)


gellyware(Posted 2005) [#5]
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.