Search code examples
c++matrixgeometrybounds

Matrix out of bounds but can't put condition to check bounds


I have a square matrix, 40 x 40, and a draw circle function that uses this formula.
I have another function that reads input from a file, the point itself (x0, y0) and the type of circle (0 or 1) and the radius.

void cerc(int x0, int y0, int r, int** matriceHarta, int tip, int n, int m)
{
    if (r == 0)
        return;
    int x, y, xx, rr;

    for (rr = r * r, x = -r; x <= r; x++)
        for (xx = x * x, y = -r; y <= r; y++)
            if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0)
            {
                if (tip == 0)
                    matriceHarta[x0 + x][y0 + y] = -5;
                else if (tip == 1)
                    matriceHarta[x0 + x][y0 + y] = -6;
            }
}

N and M are the rows and columns, but right now they are both equal. The matrix is allocated dynamically and is transmitted via the int** matriceHarta parameter.

If I put the point on (39, 39) and I give it the radius 5, the program returns a negative exit code, which I found out is an out of bounds related error. I looked over the for loops and it makes sense that that'd be the error and tried to create the condition if((x0 + x) < n && (y0 + y) < m) to check the bounds, but it still gives the error.

Question is, what am I doing wrong? For contrast, point(37, 4) with radius = 2 is OK, but point(38, 4) with radius = 2 is not OK

This is the attempted fix:

for (rr = r * r, x = -r; x <= r; x++)
        for (xx = x * x, y = -r; y <= r; y++)
            if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0 
            && (((x0+x) < n) && ((y0+y) < m))  )
            //^^^^^ this is the condition i was talking about
            {
                if (tip == 0)
                    matriceHarta[x0 + x][y0 + y] = -5;
                else if (tip == 1)
                    matriceHarta[x0 + x][y0 + y] = -6;
            }

Solution

  • The issue is that you are testing for the out-of-bounds condition after you have already accessed potential out-of-bounds elements.

    Let's break it down into separate lines:

    if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0 
               && // <-- This binds the conditions
       (((x0+x) < n) && ((y0+y) < m)))  
    

    The line above the && marked with <-- is evaluated before the line below the <--.

    In summary, the logical && is always evaluated from left-to-right, where the right side will not be evaluated if the left side evaluates to false (short-circuit boolean evaluation).

    Thus the fix is to test the bounds condition first (swap the lines in the code above).

    However, to make this a little more clear, you could break up the statement into two if statements:

    if (x0+x < n && y0+y < m)
    {
       if  (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0)
       {
            ...
       }
    }