Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting gives inconsistent results, due to loop bound

Tags:

c

Program Design, our first homework assignment was to take 4 integer values, add the 2 highest together and subtract the lowest two and square that result. Finally, compare the 2 values together to see if they are equal or not.

For example, if you were to enter: 20 10 60 40

You'd get

60 + 40 = 100

and

20 - 10 = 10 --> 10^2 = 100

So, 100 == 100

I wrote my program and tested it for various values which all returned correct results. My professor told me my program failed for all 10 test inputs and he sent me the results he got. The results he got aren't the same as mine, and I don't know what's going on. I emailed him, and he told me one of my for loops has incorrect bounds. He's right, but I still get the right results, so...?

Here's the code, any help would be appreciated!

/*
 // Author: Jesse W
 // Assignment 1

 // Desciption:
 // This program inputs four integer numbers a, b, c and d and
 // determines if the sum of the two largest numbers is the same
 // as the squared difference of the two smallest numbers
 */

#include <stdio.h>

/* Complete the code for this program below */

int main()
{
    int a, b, c, d, f, k, swap;
    int array_size = 4;
    int return_val;
    int sum, difference, square;
    int small_1, small_2, large_1, large_2;
    int array[array_size];

    //Gather input
    //printf("Enter integer values for a, b, c and d.\n");
    return_val = scanf("%d %d %d %d", &a, &b, &c, &d);

    //Validate input
    if (return_val != 4)
    {
        printf("INVALID INPUT\n");
    }
    else
    {
        //Assign values to array
        array[0] = a;
        array[1] = b;
        array[2] = c;
        array[3] = d;

        //Sort array
        for (k = 0 ; k < ( array_size - 1 ); k++)
        {
            for (f = 0 ; f < array_size ; f++)
            {
                if (array[f] > array[f+1]) /* For decreasing order use < */
                {
                    swap       = array[f];
                    array[f]   = array[f+1];
                    array[f+1] = swap;
                }
            }
        }

        //Assign sorted values to new variables
        small_1 = array[0];
        small_2 = array[1];
        large_1 = array[2];
        large_2 = array[3];

        //Compute math
        sum = large_1 + large_2;
        difference = small_1 - small_2;
        square = difference * difference;

        //Compute logic
        if(sum == square)
        {
            printf("%d equals %d.\n", sum, square);
        }
        else
        {
            printf("%d does not equal %d.\n", sum, square);
        }

        return 0;
    }
}
like image 991
Jesse Walton Avatar asked Dec 09 '22 15:12

Jesse Walton


2 Answers

f ranges up to array_size - 1

        for (f = 0 ; f < array_size ; f++)

but in that case you access array[ f + 1 ] which is array[ array_size ]

                array[f]   = array[f+1];
                array[f+1] = swap;

This results in undefined behavior. Since the value one past the end is effectively sorted as part of the array, whether the program works or not depends whether the uninitialized value is larger than all the input values.

like image 61
Potatoswatter Avatar answered Dec 11 '22 11:12

Potatoswatter


The problem is indeed the upper bound on your inner for loop; it's causing you to read past the end of your array, which causes undefined behaviour.

It's entirely possible that the resulting program still prints the correct results on your machine, but there is no guarantee that it will work on anyone else's. Hence undefined.

like image 41
Cairnarvon Avatar answered Dec 11 '22 10:12

Cairnarvon