Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

Variable length arrays/ Dynamic Memory Allocation

2020-12-24
2021-01-07
  • codesystart - 2020-12-24

    Hello,

    I am library developer & new to CodeSys OOPs programming. I have a problem where it is required to define variable size arrays & varaible size structure(DUT) objects. As i will get the information of size at runtime only.

    I want to create something like below.

    I know the below code doesnt work, but i am just trying to explain what i want to do.

    TYPE DUT :
    STRUCT
    abyReadBuffer : ARRAY[*] OF BYTE;// I dont know the size of this array. It could be maximum of 64bytes but i get this information at runtime only.
    usiVar0 : USINT;
    uiVar1 : UINT;
    END_STRUCT
    END_TYPE

    FUNCTION or FUNCTIONBLOCK (in library)
    VAR
    structure : ARRAY[*] OF DUT;// I dont know the size of this array. I get this information at runtime only.
    END_VAR

    Also the problem with above approach is i dont get the SIZE information from user, but from a status word of another FB. So i dont want any input parameters which the user needs to pass regarding size. Also the size parameter is going to change in probably every cycle/instance.

    Do i need to use Dynamic Memory Allocation for above?? If yes could anyone show me some example of it??

     
    πŸ‘
    1
  • hermsen

    hermsen - 2020-12-24

    Size isn't needed, it's implicitly given by the ARRAY via the Lowerbound and Upperbound function call.

    See help: https://help.codesys.com/webapp/_cds_datatype_array;product=codesys;version=3.5.16.0#array-of-variable-length

    // DUT
    FOR DUTIndex := LOWER_BOUND(structure ,1) TO UPPER_BOUND(structure ,1) DO
        // itterate structure[DUTIndex]
    
        // abyReadBuffer
        FOR BufferIndex := LOWER_BOUND(structure[DUTIndex].abyReadBuffer ,1) TO UPPER_BOUND(structure[DUTIndex].abyReadBuffer ,1) DO
            // itterate structure[DUTIndex].abyReadBuffer[BufferIndex]
            // Do stuff with structure[DUTIndex].abyReadBuffer[BufferIndex] here
    
        END_FOR
    END_FOR
    
     

    Last edit: hermsen 2020-12-24
  • codesystart - 2020-12-24

    Hello h-hermsen

    Thank you for the reply.

    However i made a small mistake while posting the question.

    1) VAR_IN_OUT is not permissible in DUT objects. I can somehow make it fix as it wont be greater than 64bytes.
    2) Secondly, i dont want to use VAR_IN_OUT as it is mandatory for the user to pass a fixed length array as input parameter, which is not possible for the user as he doesnt have that information.

    I hope now i make it more clear....

     
  • dFx

    dFx - 2020-12-26

    Common approach may be to size your array to the maximum size (if size is not a problem, ie on small arrays), then to use a key value to detect array end (ie nullbyte 16#00).
    This way you can fill your dut array with values and optionnaly indicate the end of dut array.
    This approach is valid only with small arrays, as reserved memory may be an issue.

     
  • codesystart - 2020-12-28

    Hello dFx,

    Firstly, in the actual data i may get null values also. I need to find some other key value maybe.

    I didnt understand you properly. How can i handle my array of DUT??

    Could you please elaborate a little?

     
  • dFx

    dFx - 2021-01-07

    Then just use an external length variable.

    For instance, your array max length is 10.
    If you only fill it with 5 items, then reset lefts items (5..9) and set your length variable to 5.

    Edit : This is how string are handled (a byte array with a max length as defined in the variable definition and then the actual length is set by the first null byte)

     

    Last edit: dFx 2021-01-07

Log in to post a comment.