shakingwindow
shakingwindow

Reputation: 101

How to assign variable length to an array in twincat3

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

Answers (1)

Jacek Domański
Jacek Domański

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:

  1. Create a new FB, instantiate it and call it in your MAIN and move your code from MAIN to the FB
  2. Add a FB_exit method to this FB. Exact naming is crucial
  3. In your FB_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:

Upvotes: 3

Related Questions