Thought I would share this here for those who care to know, I might post it on the biki as well. Anyway here it goes:
Pointers & Pass by reference
as most of you know (i hope), variables created in sqf are pointers that point to the value in memory, and dont actually store the value themselves. Prime example is creating a vehicle in a script and passing something like _veh to the result of createVehicle. _veh does not store the vehicle, it points to this object in memory, and when the vehicle gets deleted, _veh would then point to <Object-Null>, which is another place in memory thats defined at the start of the game. This is done so that a variable cant just suddenly access random memory from potentially anywhere and modify it. Would be a disaster if _veh pointed to some memory block related to OS and you tried to do some scripting action on it.
Anyway the interesting thing here is the difference between a pointer and the same pointer inside of an array. Heres an example:
You have two units, named Jack and Jill in the editor. These names are the units vehicleVarNames, so anytime you assign a variable the object, your telling the variable to point to Jack, which points to the object in the editor.
Now what happens if you decide to store Jack inside an array?
You create an array, lets say JackArray = [Jack] - and you put this inside Jacks init box - everything looks good: your storing Jack inside an array, maybe your going to have more jacks or objects to store in it for later.
But now what happens when you delete Jack?
Both Jack and JackArray will point to <Object-Null> as the object no longer exists. No complaints here.
But what happens if you want to change Jack into Jill? Jill looks cooler than Jack, so you want Jack to be like Jill, so you do:
Jill setVehicleVarName Jack;
There, now Jill will be known as Jack, so when you delete the old Jack, Jack should still reference an object (the new Jack), however, JackArray tells a different story:
Jack = Jack JackArray = [<Object-Null>];
Wait, wtf? Jack, is not the same? The array itself holds only pointers, not copies of objects like in Java. So what gives? How does that Jack point to null?
The Reason:
The array containing [Jack], the pointer, is not the same pointer as Jack. [Jack] is defined once when being stored inside the array - pointing to the original object. Even if Jack points to a new object, [Jack] does not follow suite. Therefore one can say that
Jack != [Jack]
These are not the same variables. Arrays in sqf appear to behave similar to arrays in Java - the array creates a copy of its contents, which in sqf's case, is the pointers.
So if you had an array holding players for whatever reasons, you need to take into account that, if a player respawns, the pointer in the array will still point to the old player object, not the new one. There doesn't seem to be a solution to fixing this as of right now. You will need to re-add all the objects into your array again using the new pointers, which can be tedious if your not sure which index it is in.
Im not sure how many people will find this information useful, but it definitely had me stuck on something for quite some time. This is one of those niche things, that as you get better and more understanding in sqf, will be invaluable later on.
Discuss
HOME
Reply With Quote