array as parameter

BlitzMax Forums/BlitzMax Beginners Area/array as parameter

Drakim(Posted 2008) [#1]
I'm just wondering, if you pass an array as a parameter, is a reference to the original array sent, or is a copy of the array sent?

And, is there a way to make one or the other happen? I can see the need to use both in different situations, but I have no idea on how to do it.


Perturbatio(Posted 2008) [#2]
take a look at the var and varptr commands


SebHoll(Posted 2008) [#3]
if you pass an array as a parameter, is a reference to the original array sent

Yes, it is sent as a pointer, just like all BlitzMax type instances/objects.

If you want to work on a copy of an array, just make a temporary copy at the start of the function using slicing. See this example below:

Local myArray:Int[] = [0, 1, 2, 3, 4 ]
ChangeArray(myArray)
ChangeArrayCopy(myArray)
Print myArray[1]

Function ChangeArray( pArray:Int[] )
	pArray[1] = -1
EndFunction

Function ChangeArrayCopy( pArray:Int[] )
	pArray = pArray[..]		'We can quickly make a copy of the array using slicing
	pArray[1] = -2
EndFunction



Yan(Posted 2008) [#4]
Yes, it is sent as a pointer, just like all BlitzMax type instances/objects.
Although not quite, it seems...

http://www.blitzbasic.com/Community/posts.php?topic=64441#719440

8o|


taxlerendiosk(Posted 2008) [#5]
When you slice an array, you are not actually modifying it (like you are when you change one of its values) but instead creating an entirely new array, and copying some of the elements of the old one into it.


Drakim(Posted 2008) [#6]
Okay, now I'm kinda confused. Some say that it's only when I slice that the array is copied, and that it's the reference being passed in the parameter, but the "var" command seems to be the thing that is supposed to cause this.

Does arrays sort of have a "var" effect to them as default?


Brucey(Posted 2008) [#7]
Usually, when you pass an array into a method/function as a parameter, you can modify the contents of the array, and those changes are reflected outside of the method/function - since the array you passed in was not a copy, but a reference to it (the pointer in memory).

If, in the method/function you do something like :
pArray = pArray[..]

What actually happens is you get a "new" array at a new location (pointer) in memory. It is copied.
The local reference (pointer) to the original array is lost, and any changes you make to this new array are to it alone. The original array is not modified.

Now, if you add "Var" to the method/function definition for your array parameter, you are essentially referring to the pointer of the array, rather than the array itself.
This means, if you do
pArray = pArray[..]

rather than creating new array at a different memory location, it will create the new array in the same memory location, overwriting the old data. Outside of the method/function the original array that you passed in will now appear as this new array.

...or something like that.


Drakim(Posted 2008) [#8]
Ah, thanks, I understand now.


However, on a sidenote, how does this work for TImages? I disscovered now while coding that simply setting one TImage variable to another TImage doesn't actually make two images, but makes them point to the same one. (correct me if I'm wrong though)

So, how do I ensure that I copy a new TImage when passing it to another variable?


Dreamora(Posted 2008) [#9]
by using a method to do so. but its stupid to copy an image as image data use massive amount of RAM even when not needed because 2 images from the same file on the disk are exactly the same. so why keep 2 distinct copies of the binary data in RAM?


Drakim(Posted 2008) [#10]
Because the images gets modified. Right now, when I modify one picture, the other one is modified too. Which is obviously not what I want >>

But, "by using a method to do so" I don't understand. Method? Obviously there must be something inside the method that does the trick?


Drakim(Posted 2008) [#11]
Nobody? I've been pretty much stuck since I ran into this problem. How do I duplicate a TImage instead of passing the pointer?


tonyg(Posted 2008) [#12]
How quick does it have to be? What is the aim? The simplest is to lockimage to gain a pixmap and then loadimage that pixmap.


Drakim(Posted 2008) [#13]
That sounds awful slow. I'll use it so I can continue on other things, but I'd really like it if anybody knew the proper way to do this.


tonyg(Posted 2008) [#14]
How quick does it have to be?

That sounds awful slow.

Well, How quick DOES it have to be? What is the aim? Did you try it? Actually cloning the image takes 0ms but drawing it might take a bit of a hit.
I'd really like it if anybody knew the proper way to do this.

Proper way to do what? Clone an image or achieve a specific task?
As above, creating a copy of the image is quick but it depends what you want to do with it next.


Drakim(Posted 2008) [#15]
I simply have TImage variables A and B. I wish to copy A to B, without them "sharing" the image, but having two indivdual images. If I just try to set B to A, then the image gets shared, and if you manipulate one, you manipulate both.

It might not be slow, I dunno, but it sounded awful slow to convert an TImage to a Pixelmap and then back to a TImage.

When I ment a "proper way to do it", I ment simply a way to copy an image, instead of making more pointers to to the same image. Surely there must be some better way that to convert the image TWICE to get two of the image?


tonyg(Posted 2008) [#16]
So DID you try it? Was it too slow?
You can loadimage the myimage.pixmaps[n] into a new TImage if you want.

Both the methods will struggle to get above 0ms for the conversion.


Drakim(Posted 2008) [#17]
Oh well then, I'll do that then. ><

But there is still some part of me screaming "YOU ARE DOING IT WRONG!".


tonyg(Posted 2008) [#18]
If it works and it works quick enough then it's not wrong... surely.
What is it you expect to be able to do?
The drawn object doesn't exist except as a surface in Video RAM. This surface is connected to a texture (image). This texture is built from a pixmap held in a field of the TImage object.
You *could* go to the DX or GL level and mess about with creating surfaces, linking it to an object, creating a pixmap etc, OR you could let Bmax do iall that for you as per the code above.
If it helps then create a Function called CopyImage :