Playing with 'new' identifier and pointers.

BlitzMax Forums/BlitzMax Programming/Playing with 'new' identifier and pointers.

AarbronBeast(Posted 2005) [#1]
Something funky is going on when using the same variable to create new objects multiple times. Can anyone figure this one out?

Type T
    Field x
End Type

Local a:T
Local p1:T Ptr         ' A pointer to T.
Local p2:T Ptr         ' Another pointer to T.

' Set up first object.
a = New T
a.x = 10
p1 = VarPtr a          ' Store address of first object.
Print p1[0].ToString() ' Prints address 0x18029f8.  OK.

' Set up second object using same variable.
a = New T
a.x = 20
p2 = VarPtr a          ' Store address of second object.
Print p2[0].ToString() ' Prints 0x1802a28.  Different address.  Good!

Print p1[0].ToString() ' Prints 0x1802a28. Wha happen??  Why did it change?
Print p2[0].ToString() ' Prints 0x1802a28.
Print p1[0].x          ' Prints 20 due to mem address change.  Don't want this to happen!
Print p2[0].x          ' Prints 20.  OK.


Thanks.


Robert(Posted 2005) [#2]
The code "VarPtr a" does not return the address of the object a, it returns the address of the reference to the new T object (which is what 'a' is, just a reference).

Therefore when you reassign the reference 'a' using the second 'a=New T', p1[0] will access the new object.


ziggy(Posted 2005) [#3]
the second time you make a = new T, the first T object raises reference counting = 0, so, the old address can point to anywhere!


AarbronBeast(Posted 2005) [#4]
Ah, so it is. Thanks Robert.

And ziggy, using pointers, therefore, is not the proper way to store a set of objects since it does not increase the reference count. Right?

I am trying to figure out the "correct" way to store a list of object references (in a 2 dimensional array). The TList doesn't serve my needs as well as I would like. And I cannot create an array of variables of type 'T'. So, this is what I have come up with now. Any thoughts?

		For y = 1 To down
			For x = 1 To across
				tempTile = TTile.Create(0, 0, width, height)

				' Add reference to tileArray.
				tileArray[x-1,y-1] = tempTile
			Next
		Next


This seems to work OK in my tests. Does anyone see any problem with this approach. Does anyone see a more "correct" approach?

Thanks for any/everyone's help.


ziggy(Posted 2005) [#5]
Why isn't TList filling your needs?


AarbronBeast(Posted 2005) [#6]
Because TList is a one-dimensional linked list which does not provide me with the 2 dimensional indexing capabilities that I'm looking for. I suppose I can always just create a function that takes an x and a y as parameters, then do ((y * width) + x) to determine the position in a one dimensional list, and then FindNext() to that TList node. But I'm trying to find out if there is a better way.


jamesmintram(Posted 2005) [#7]
Could you not have a list of lists? Ie x would reference the particular list and y would reference the Item in the specified list.


Robert(Posted 2005) [#8]
And I cannot create an array of variables of type 'T'.


Yes you can! Objects are always passed by reference in BlitzMAX, so just declare a two dimensional array like so:

Local myArray:T[firstDimensionSize,secondDimensionSize]


This means "create a new two dimension array of references to T objects".


AarbronBeast(Posted 2005) [#9]
Sheeeoooot, you are right, Robert. I wonder how I missed that! I must not have implemented it properly.

Thanks for the kick in the butt!

jamesmintram, pretty good idea with the list of lists, it should be doable, but I still wouldn't have the indexing feature that I want. I would need to step through each node on the main list, and then step down through the link in the sub list until I get to the (x, y) that I want. Too much.

The array that Robert just mentioned will work beautifully.