I need to change the length of the array dynamically.Right now the code looks like this:
VAR
arrData : ARRAY[1..200] OF INT;
length : INT := 200;
END_VAR
The size of the array depends on the length variable.Here the value of length variable can be changed during runtime using the VISU(gui). So if I change the value of the length = 180 then 20 bytes of arrData are unused.Is there a way to declare the array as variable length similar to vectors in c++ such that the memory is not assigned during declaration but during runtime.
Edit: How to deallocate the memory safely?
PROGRAM MAIN
VAR
arrData : POINTER TO INT;
length : INT := 200; // can be changed at runtime
bNew : BOOL := TRUE;
oldLength : INT; // to hold the old length variable
isInit : BOOL := FALSE;
END_VAR
IF NOT isInit THEN
oldLength := length; // initialise only once
isInit := TRUE;
END_IF
// if length is changed during runtime then delete the array
IF oldLength <> length THEN
IF arrData <> 0 THEN
__DELETE(arrData);
bNew := TRUE;
END_IF
oldLength := length;
END_IF
// during the first run or when the length is changed
IF bNew THEN
arrData := __NEW(INT,length);
bNew := FALSE;
END_IF
// deallocate the memory when the MAIN program goes out of scope
// as we are not deleting the array when the length variable is not
// changed during runtime
END_CASE
The way to do it is to use
__NEW__NEW in InfosyspMyPointer := __NEW(INT, length);__NEWwill return a pointer to first element of an array. You can access latter elements by offsetting this pointer.You can check if
lengthwas changed by comparing value from this and previous cycle. If so,__DELETEthe old array and initialize a new one.Edit:
I think, that you get your error the moment TwinCAT runtime is stopped, as the momory allocated by
__NEWis not freed at that point.Your code should be placed not in a Program (
PRG) but in a Function Block (FB). The reason for that is that you need to implementFB_exitmethod (This method is called implicitly when FB instance is destroyed, i.e. when stopping TwinCAT runtime like you do by activating configuration). There is no equivalent method for aPRGas far as I know.To do this:
FB, instantiate it and call it in yourMAINand move your code fromMAINto theFBFB_exitmethod to thisFB. Exact naming is crucialFB_exitmethod write the following code:This method will be called every time you stop your runtime and free the memory.
Links to Infosys:
pMyPointer <> 0but more readable