openroberta-lab icon indicating copy to clipboard operation
openroberta-lab copied to clipboard

[NXT] Expanding arrays (lists) is possible in simulator, but not on the NXT

Open stex opened this issue 7 years ago • 3 comments

Describe the bug

Orlab allows me to set values at array indices which are higher than the originally initialized array, leading to a segfault (or "File Error") as a memory address is requested which does not exist.

I'm a bit rusty regarding C programming, but see below for an example program which actually lets you expand array more or less dynamically. I'm sure there is a way to wrap this into a procedure, I wasn't able to for this example though.

To Reproduce Steps to reproduce the behavior:

  1. Write a program like the following: image

  2. Send it to the NXT

  3. Run it

  4. Be presented with "File Error" and a halted execution

The generated program:

#define WHEELDIAMETER 5.6
#define TRACKWIDTH 12.0
#define MAXLINES 8 
#include "NEPODefs.h" // contains NEPO declarations for the NXC NXT API resources 
 
float numbers[1];
float row;
task main() {
    float __numbers[] = {0};
    numbers = __numbers;
    row = 0;
    SetSensor(S1, SENSOR_TOUCH);
    SetSensor(S2, SENSOR_SOUND);
    SetSensor(S3, SENSOR_LIGHT);
    SetSensor(S4, SENSOR_LOWSPEED);
    for (int i = 1; i < 8; i += 1) {
        numbers[i] = i;;
    }
    for (int j = 0; j < 8; j += 1) {
        row = j + 1;
        NumOut(0, (MAXLINES - row) * MAXLINES, numbers[j]);
    }
    while (true) {
        if ( Sensor(S1) == true ) {
            break;
        }
        Wait(15);
    }
}

Expected behavior

Either the same behaviour as in the simulator or orlab not giving me the opportunity to set array indices which are higher than the initially set ones.

image

Additional context

This looks a bit clunky, but actually works:

#define WHEELDIAMETER 5.6
#define TRACKWIDTH 12.0
#define MAXLINES 8
#include "NEPODefs.h" // contains NEPO declarations for the NXC NXT API resources

float numbers[1];
float row;

task main() {
    float __numbers[] = {0};
    float tmpAry[];
    int requiredAdditionalIndices;

    numbers = __numbers;
    row = 0;
    SetSensor(S1, SENSOR_TOUCH);
    SetSensor(S2, SENSOR_SOUND);
    SetSensor(S3, SENSOR_LIGHT);
    SetSensor(S4, SENSOR_LOWSPEED);
    for (int i = 1; i < 8; i += 1) {
        // Find out if we need to expand the array
        requiredAdditionalIndices = i - (ArrayLen(numbers) - 1);

        // If an index was requested that's already covered by the array,
        // we don't need to do anything.
        if (requiredAdditionalIndices > 0) {
          // Generate an array of the needed sizes, filled with zeroes
          ArrayInit(tmpAry, 0, requiredAdditionalIndices);

          // Append the newly built array to the one to be expanded
          ArrayBuild(numbers, numbers, tmpAry);
        }

        numbers[i] = i;
    }
    for (int j = 0; j < 8; j += 1) {
        row = j + 1;
        NumOut(0, (MAXLINES - row) * MAXLINES, numbers[j]);
    }
    while (true) {
        if ( Sensor(S1) == true ) {
            break;
        }
        Wait(15);
    }
}

stex avatar Nov 11 '18 19:11 stex

  • for now arrays will not be re-allocated
  • set operation does not expand the array, it only modifies the specified element of the existing array
  • indices will be sanitised to halt the program and show the message when the out-of-bounds occurs
  • simulator should not allow modification of the existing arrays JS-style, rather sanitise the index in set and get operations as well

VinArt avatar Nov 16 '18 10:11 VinArt

@VinArt please move this issue to "in progress", because you have already commited on this. Thank you

bjost2s avatar Nov 29 '18 11:11 bjost2s

What is the current state of this issue?

bjost2s avatar Feb 21 '19 19:02 bjost2s