If you’re starting to program with Xojo, then you’ll probably soon find yourself in a situation where you need to use one of the Container types: Array. In this case, it’s also probable that you might be confused at first as to why you don’t get what you expected when assigning the contents of a source Array to a target Array via the assignment operator (“=”).
After all, when using the following snippet of code we could (wrongly) expect that the contents stored in the
ATarget Array would be the same that the ones stored in the
ASource Array. Of course, and at a first glance, this is the case. Try to write the following fragment in the Opening Event of a new Xojo Project or Method created by yourself (don’t forget to call such method, if you decide to follow that path):
Var ASource() As Integer = Array(1,2,3,4,5,6,7,8) Var ATarget() As Integer ATarget = ASource
If you set a breakpoint in the last line of code and execute your test app, then you’ll see that, as exepected, the contents of the
ATarget() Array are the same that the ones stored by the
ASource() Array. (Navigate through the Debugger Inspector Panel to inspect these variables)
However, what happens if we add the following line of code at the end of our fragment of code?:
In this case we will be redimensioning the storage capacity of our
ASource() Array with a total of 0 items. That is, in practice we will be emptying the Array.
As result of this operation you could expect that, while the contents of the
ASource() variable are emptied, your
ATarget() Array will continue storing their items.
The truth is that it doesn’t.
This is how Array Assignment Works
When we use the assignement operator (=) to set the values (items) of an Array to another one, what in fact happens behind the scenes is that the target Array will store only a reference to the source Array (the right-side value of the assignement operator), and not a copy of the values/objects stored.
Thus, and because they are references, all the operations we do on the source Array will be reflected in the target Array.
If you want to see that for yourself, try to delete the previous breakpoint and put a new one in the last line of code added.
When you run the now modified code, using the IDE Debugger feature to run the line of code where the Debugger has stopped, you’ll see how both Array variables (
ATarget) reveal that their dimensions are -1. That is: when you clean the source Array using the
ResizeTo method that change is also reflected in the target Array.
Why does this happens?
Better Understanding: Reference vs Copy
All the apps you execute in your computer or any other device are stored in memory, both the code to be executed and the Objects created and used during all the application lifetime.
For example, when we declare a variable in our example code (in this case an Array of Integer type), we can think about that variable as a mere label pointing to the starting cell of memory where will be stored the values later. We could visually represent that as this:
So, this could be the visual representation of the memory when we add new items on the Array, although the real Xojo implementation of the stored values for an Array can differ from this. It doesn’t needs to be a contiguous region of memory or even the same structure to represent an Array in memory:
However, when we use the assignment operator (“=”) to set the contents of our
ASource() Array to the
ATarget Array what happens is that the value set for the
ATarget() variable is the same memory position used by the
ASource() variable; so all the operations made on the
ASource() object (memory region) will be also reflected on
Conversely, when we iterate the items stored in the
ASource() Array and use the
Add method on the
ATarget() Array, what happens is that the target Array will get and use its own memory region to store its own copy of the added values and, thus, is independent of the memory region used by the source Array.
This way, all the opeations made on the items pointed by the source Array will not be reflected on the target Array:
Copying Array Items
So, if what we really want to do is have our target Array stores its own copies of a source Array items, then we need to change from a simple assignment to an iteration and addition of the iterated values.
For that we need to use the
Add Method on the target Array; while to access every item stored in the source Array we need to employ its index position in the Array (for example,
ASource(0) will get the first item stored in the Array, while
ASource.LastIndex will gives us the index position of the last added value).
Replace the previous code example with this one:
Var ASource() As Integer = Array(1,2,3,4,5,6,7,8)
Var ATarget() As Integer Var Max As Integer = ASource.LastIndex For n As Integer = 0 to Max ATarget().Add ASource(n) Next ASource.ResizeTo(-1)
Now, if you set the a Debugger breakpoint in the last line of code and execute the application, then you’ll see, after executing the last line of code, our
ATarget() Array will keep its own set of values, even after redimensioning the
ASource() Array with the equivalent to “reserve storage for no items”, thus cleaning the region of memory used by such variable.
You can see all this in action in the following video (in Spanish):
Javier Rodriguez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has be using Xojo since 1998. He manages AprendeXojo.com and is the developer behind the GuancheMOS plug-in for Xojo Developers, GuancheID, AXImageCanvas, Markdown Parser for Xojo, HTMLColorizer for Xojo and the Snippery app, among others.