Reputation: 101
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
Upvotes: 2
Views: 1592
Reputation: 640
The way to do it is to use __NEW
__NEW in Infosys
pMyPointer := __NEW(INT, length);
__NEW
will return a pointer to first element of an array. You can access latter elements by offsetting this pointer.
You can check if length
was changed by comparing value from this and previous cycle. If so, __DELETE
the 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 __NEW
is 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 implement FB_exit
method (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 a PRG
as far as I know.
To do this:
FB
, instantiate it and call it in your MAIN
and move your code from MAIN
to the FB
FB_exit
method to this FB
. Exact naming is crucialFB_exit
method write the following code:IF __ISVALIDREF(arrData) THEN
__DELETE(arrData);
END_IF
This method will be called every time you stop your runtime and free the memory.
Links to Infosys:
pMyPointer <> 0
but more readableUpvotes: 3