Limiting Memory Access of an Array to Within its Bounds

2024-03-05
2024-03-06
  • john-robinson - 2024-03-05

    Recently we had an issue regarding some simple code to calculate a rolling average. The code indexes from zero to 199 to properly store the current input into a circular buffer which then allows us to calculate a rolling average:

    VAR
        input_5s : REAL;
        outs_arr : ARRAY[0..199] OF REAL;
        i : USINT := 0;
    END_VAR
    ___
    //this code runs every five seconds, calculating a rolling average
    outs_arr[i] := input_5s;
    i := i + 1;
    output := OSCAT_BASIC.ARRAY_AVG(ADR(outs_arr), SIZEOF(outs_arr));
    IF i >= SIZEOF(outs_arr) THEN i := 0; END_IF
    

    There is a simple bug in this code where the index will be set to 0 when it has surpassed the length of the array in bytes (800 in this case) rather than larger than the number of reals in the array (200). The solution here is simple, replacing i >= SIZEOF(outs_arr) with i >= SIZEOF(outs_arr)/SIZEOF(outs_arr[0]).

    In this example when the index increased to 201 and the line outs_arr[201] := input_5s was called, codesys arbitrarily wrote to the address in memory that is where outs_arr[201] would be if the array was that long. I would like to find a way to wrap the codesys array inside of a wrapper class that checks if an input is within the bounds of an array before writing to that value. I know how I would implement that for a specific array, I could create a method or class that takes an input of an array of variable length, ie. ARRAY[*] OF REAL, but I don't know how to make this for any data type.

    I am wondering if anyone has ever done anything similar to this, or has any better suggestions to ensure that none of the programmers on this application accidentally create code that can arbitrarily write to other locations in memory.

     
  • TimvH

    TimvH - 2024-03-06

    Add the object "POU for Implicit Checks" to your application, then select "Bounds check".
    This will create a function which is automatically called each time an array is write accessed. In the function you can handle "out of bounds" situations. By default it will be limited to its lower or upper bound.

     
  • john-robinson - 2024-03-06

    Thanks Tim!
    This was exactly the functionality we were looking for. We are already using implicit checks to check for divide by 0 errors, we will add implicit checking for array bounds.

     

Log in to post a comment.