Frogg1ven
Frogg1ven

Reputation: 41

simplest way to prevent accesing array beyond range in C

I'm wondering if there is any easier way to prevent accessing array beyond range than using if() statement. I have switch case code for arduino like this with many cases:

switch(a){
    case 3:     
    case 27:  
      for (int i = 0; i < 8; i++){
        leds[ledMapArray[x][i]] = CRGB(0,255,0);
        leds[ledMapArray[i][y]] = CRGB(0,255,0);
        if ((x + i < 8) && (y + i < 8))     leds[ledMapArray[x + i][y + i]] = CRGB(0,255,0);
        if ((x - i >= 0) && (y - i >= 0))   leds[ledMapArray[x - i][y - i]] = CRGB(0,255,0);
        if ((x + i < 8) && (y - i >= 0))    leds[ledMapArray[x + i][y - i]] = CRGB(0,255,0);
        if ((x - i >= 0) && (y + i < 8))    leds[ledMapArray[x - i][y + i]] = CRGB(0,255,0);    
        }
      break;
    case 4:   
    case 28:  
      if (x + 1 < 8)                      leds[ledMapArray[x + 1][y]] = CRGB(0,255,0);
      if (x - 1 >= 0)                     leds[ledMapArray[x - 1][y]] = CRGB(0,255,0);
      if (y - 1 >= 0)                     leds[ledMapArray[x][y - 1]] = CRGB(0,255,0);
      if (y + 1 < 8)                      leds[ledMapArray[x][y + 1]] = CRGB(0,255,0);
      if ((x + 1  < 8) && (y + 1 < 8))    leds[ledMapArray[x + 1][y + 1]] = CRGB(0,255,0);
      if ((x - 1  >= 0) && (y - 1 >= 0))  leds[ledMapArray[x - 1][y - 1]] = CRGB(0,255,0);
      if ((x + 1  < 8) && (y - 1 >= 0))   leds[ledMapArray[x + 1][y - 1]] = CRGB(0,255,0);
      if ((x - 1  >= 0) && (y + 1 < 8))   leds[ledMapArray[x - 1][y + 1]] = CRGB(0,255,0);    
      break;
...

ledMapArray is 8x8 array where x and y value may be <7,0>. Here are some definitions:

// CRGB is structure from FastLed library
CRGB leds[NUM_LEDS]; // from FastLed library to control LED strip
// Array to show how LED strip looks like, values in array represents leds
const short ledMapArray[8][8] = {{0,  1,  2,  3,  4,  5,  6,  7},
                                 {15, 14, 13, 12, 11, 10, 9,  8},
                                 {16, 17, 18, 19, 20, 21, 22, 23},
                                 {31, 30, 29, 28, 27, 26, 25, 24},
                                 {32, 33, 34, 35, 36, 37, 38, 39},
                                 {47, 46, 45, 44, 43, 42, 41, 40},
                                 {48, 49, 50, 51, 52, 53, 54, 55},   
                                 {63, 62, 61, 60, 59, 58, 57, 56}};

The point of this switch case is to light up specific LEDs from LED strip. I want to show allowed moves for chess pieces on smart chessboard. Is there any better way to do this?

Upvotes: 0

Views: 85

Answers (1)

Bodo
Bodo

Reputation: 9875

The Answer was written when the question used the tag c, not c++ and edited later. The FastLED library is clearly implemented in C++.

You could wrap the array access in a function that implements the checks.

The following function assumes that the array leds and ledMapArray are file scope variables. Otherwise the function would need more arguments. In C++, the function will also work if the function and the variables are members of the same class.

Instead of a hard-coded number 8, the check should better be implemented based on the number of elements in the array. (Something like sizeof(array)/sizeof(array[0]). I would need to see the definition of leds and ledMapArray.)

Note that the function implements a bounds check for ledMapArray only, not for leds.

void setLed(int x, int y, some_type crgb)
{
    if((x >= 0) && (x < 8) && (y >= 0) && (y < 8))
    {
        leds[ledMapArray[x][y]] = crgb;
    }
}

The function could also be replaced with a macro which would work for local array variables as well as for global variables.

#define setLed(x, y, crgb) do { \
    if((x >= 0) && (x < 8) && (y >= 0) && (y < 8)) { \
        leds[ledMapArray[x][y]] = crgb; \
    } \
} while(0)
switch(x){
    case 3:     
    case 27:  
      for (int i = 0; i < 8; i++){
        setLed(x, i, CRGB(0,255,0));
        setLed(i, y, CRGB(0,255,0));
        setLed(x + i, y + i, CRGB(0,255,0));
        setLed(x - i, y - i, CRGB(0,255,0));
        setLed(x + i, y - i, CRGB(0,255,0));
        setLed(x - i, y + i, CRGB(0,255,0));    
        }
      break;
    case 4:   
    case 28:  
      setLed(x + 1, y, CRGB(0,255,0));

/* etc ... */

Instead of repeatedly using anonymous objects with the same constructor CRGB(0,255,0), you could use a named object.

CRGB greenColor(0,255,0);

        setLed(x, i, greenColor);
        setLed(i, y, greenColor);
        /* etc ... */

Or use pre-defined color objects from the library.

        setLed(x, i, CRGB::Green);
        setLed(i, y, CRGB::Green);
        /* etc ... */

Upvotes: 4

Related Questions