sarogahtyp 1108 Posted August 4, 2016 Hey guys in another topic it came to the question how pointers are handled in sqf. I know them from C and I know they are sometimes essential if u want to write fast code. The question is, how can I get a pointer of an array and how can I return it from and pass it to functions and how can I do the same with a complete copy of an array? Share this post Link to post Share on other sites
gc8 977 Posted August 4, 2016 To get pointer: _array1 = [1,2,3]; _array2 = _array1; _array2 now points to _array1. changes made to either of the arrays applies to both arrays. To get copy: _arrayCopy = + _array1; _arrayCopy now has copy of _array1 contents. I don't know how pointers work in sqf when returning from function, I assume the same way. 1 Share this post Link to post Share on other sites
sarogahtyp 1108 Posted August 4, 2016 (edited) okay I should have read this better :-) just for reference (these are thoughts only. I ve tested nothing of it): pass pointer: _array = [0,1,2]; [_array] call any_function; //this can be bad if spawn is used instead of call because if the main function is finished then the local _array should be destroyed and the passed pointer will then point nowhere. pass a copy: _array = [0,1,2]; [+_array] call any_function; return pointer: any_fnc = { _array = [0,1,2]; _array }; // this should not work with a local array because it should be destroyed after any_fnc is finished... but syntax should be fine:-) return copy: any_fnc = { _array = [0,1,2]; +_array }; EDIT:As gc8 said below I could be wrong with my comments in these snippets... Edited August 4, 2016 by sarogahtyp 1 Share this post Link to post Share on other sites
gc8 977 Posted August 4, 2016 _array = [0,1,2];[_array] call any_function; //this can be bad if spawn is used instead of call because if the main function is finished then the local _array should be destroyed and the passed pointer will then point nowhere. have you tested it? I was thinking that maybe sqf uses shared pointer system so that the array would be valid at any time inside the function. 1 Share this post Link to post Share on other sites
sarogahtyp 1108 Posted August 4, 2016 have you tested it? I was thinking that maybe sqf uses shared pointer system so that the array would be valid at any time inside the function. I should ve written it. I tested nothing of it. these r thoughts only. I will update the post above with that information. Share this post Link to post Share on other sites
gc8 977 Posted August 4, 2016 ok I tested with this: _array = [1,2,3]; TestFn = { _a = _this select 0; sleep 1; hint format["_a = %1",_a]; // prints _a = [1,2,3] }; [_array] spawn TestFn; so it seems to work even the initial _array goes out of scope. Share this post Link to post Share on other sites
sarogahtyp 1108 Posted August 4, 2016 idk if we talk bout the same. I meant something like this: TestFn = { _a = _this select 0; sleep 1; hint format["_a = %1",_a]; // prints _a = [1,2,3] }; OuterFn = { _array = [1,2,3]; [_array] spawn TestFn; }; call OuterFn; Share this post Link to post Share on other sites
gc8 977 Posted August 4, 2016 idk if we talk bout the same. I meant something like this: TestFn = { _a = _this select 0; sleep 1; hint format["_a = %1",_a]; // prints _a = [1,2,3] }; OuterFn = { _array = [1,2,3]; [_array] spawn TestFn; }; call OuterFn; that still prints "_a = [1,2,3]" 1 Share this post Link to post Share on other sites
pedeathtrian 100 Posted August 4, 2016 To get copy: _arrayCopy = + _array1; _arrayCopy now has copy of _array1 contents. I'd a bit extend, if you don't mind: To get a deep copy: _arrayCopy = + _array1; To get a shallow copy: _arrayCopy = [] + _array1; Example: _a = ["foo", "bar"]; _b = ["baz", "qux"]; _c = [_a, _b]; _d = +_c; // _d is no longer related to _a or _b _e = []+_c; // does not copy _a and _b, but copies pointers to their data _d select 0 set [0, "nobody expects"]; // _a is still ["foo", "bar"]; _d is [["nobody expects", "bar"], ["baz", "qux"]] _e select 0 set [0, "spanish inquisition"]; // _a is ["spanish inquisition", "bar"]; _d is [["nobody expects", "bar"], ["baz", "qux"]]; _e is [["spanish inquisition", "bar"], ["baz", "qux"]] In general, every time (incl. passing args to and returning from functions) you deal with array you deal with pointer to it only, unless you have explicit deep copying. Therefore if function creates copy of array it should inform user of it. Otherwise is very bad taste. UPD. I was thinking that maybe sqf uses shared pointer system so that the array would be valid at any time inside the function. Exactly. Therefore array exists while at least one variable (i.e. name in script) points to its data. You return from function, local pointer (not array) expires, external continues to hold that data. 2 Share this post Link to post Share on other sites
jwllorens 43 Posted August 4, 2016 Alright, I haven't tested this, but thinking through the following script, I am pretty sure this is how it works. _variable1 = 5; _variable2 = _variable1; //_variable2 is now a copy of _variable1. Any change to either will have no effect on the other. _variable1 = "hello world"; hint str _variable2; //will display the number 5. //Arrays are a little different. _array1 = [[1,2,3],[4,5,6]]; _array2 = _array1; //_array2 and _array1 are both pointers to the array. Any change made to either _array1 or _array2 will be reflected by both variables. _array1 pushBack [7,8,9]; hint str _array1; //will obviously display [[1,2,3],[4,5,6],[7,8,9]] sleep 5; hint str _array2; //will also display [[1,2,3],[4,5,6],[7,8,9]] //we can also maintain pointers to the same array in different scripts, and therefore manipulate data in one script from another script. _array1 spawn { _array3 = _this; _array3 set [0,"Tom"]; _array3 set [1,"Dick"]; _array3 set [2,"Harry"]; }; sleep 5; hint str _array2; //will display ["Tom","Dick","Harry"] //what happens if we start changing the variables? _array2 = "sausages"; sleep 5; hint str _array1; //will hint ["Tom","Dick","Harry"] sleep5; hint str _array2; //will hint sausages. //So the array still exists out there, but _array2 no longer points to it. How can we destroy the array? _array1 = nil; //The array ["Tom","Dick","Harry"] is now gone and no longer in memory. //The array is not destroyed because we set the pointer _array1 to nil. //The array is destroyed because there are no more pointers that point to it. //What about other methods of getting and setting variables? myGlobalVariable = ["cheese","burger"]; //Now we have a global variable that points to ["cheese","burger"] //Lets see what happens if we start passing this global variable around all over the place. _myVar1 = missionNamespace getVariable "myGlobalVariable"; _myVar2 = myGlobalVariable; sleep 5; _myVar1 pushBack "with"; hint str myGlobalVariable; //will display ["cheese","burger","with"] sleep 5; _myVar2 pushBack "pickles"; hint str myGlobalVariable; //will display ["cheese","burger","with","pickles"] _myVar2 spawn { _this set [3,"tomatoes"]; }; sleep 5; hint str myGlobalVariable; //will display ["cheese","burger","with","tomatoes"] missionNamespace setVariable ["myGlobalVariable",["communism","capitalism"]]; //myGlobalVariable should now point to a different array, in this case, ["communism","capitalism"] hint str myGlobalVariable; //will display ["communism","capitalism"] //however, our array ["cheese","burger","with","tomatoes"] is not gone, it still exists in memory because we have some local variables pointing to it //this is important to note. _myVar1 and _myVar2 do not point to the myGlobalVariable pointer, they instead point directly to the original array. //setting the myGlobalVariable pointer to point at a new array does not redirect variables that were defined with _varName = myGlobalVariable sleep 5; hint str _myVar1; //will display ["cheese","burger","with","tomatoes"]; //but what if we want changes in an array done to an array to be unique to that variable and not reflected in all other variables pointing to the same array? //We make a copy of the array _myVar2 = + _myVar1; _myVar2 deleteAt 0; hint str _myVar1; //will display ["cheese","burger","with","tomatoes"] sleep 5; hint str _myVar2; //will display ["burger","with","tomatoes"] //note that using + makes a deep copy. Lets examine what that means using some new arrays. First we will redefine our old variables. _myVar1 = [["ham","burger"],["hot","dog"]]; _myVar2 = + _myVar1; _mySubArray = _myVar2 select 0; _mySubArray set [0,"tofu"]; hint str _myVar1; //will display [["ham","burger"],["hot","dog"]] sleep 5; hint str _myVar2; //will display [["tofu","burger"],["hot","dog"]] 1 Share this post Link to post Share on other sites