Sorting gives inconsistent results due to loop binding

The design of the program, our first homework, was to take 4 integer values, add the 2 highest values ​​together and subtract the least two and the square of this result. Finally, compare the two values ​​together to make sure they are equal or not.

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

You'll get

 60 + 40 = 100 

and

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

So 100 == 100

I wrote my program and tested it for various values ​​that all returned the correct results. My professor told me that my program failed for all 10 test materials, and he sent me the results that he received. The results do not match mine, and I do not know what is happening. I emailed him and he told me that one of my cycles has incorrect ratings. He's right, but I still get the right results, so ...?

Here is 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; } } 
+4
source share
5 answers

f has a range up to array_size - 1

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

but in this case you get access to array[ f + 1 ] , which is array[ array_size ]

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

This leads to undefined behavior. Since the value past the end is effectively sorted as part of the array, regardless of whether the program is running or not, whether the value of the uninitialized value is greater than all the input values.

+8
source

The problem is really the upper limit of your inner for loop; this forces you to read beyond the end of your array, which causes undefined behavior.

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

+4
source

In your inner loop there will be access to array[4] , which invokes undefined behavior. Once you run undefined behavior, you cannot guarantee anything about the program after this point.

Most likely, what actually happens is that on your computer, array[4] simply larger than array[3] , and you keep them in the same order. On your professor’s computer, you change them (possibly corrupting some other variable), making array[3] that value undefined.

+2
source

Since your program output completely depends on the value of array[4] , where array is an array of length 4, its behavior is completely unpredictable: there is no way from the source to guess what value will take place in memory in the place of array + 4 .

(Actually, this is even worse than this program causing undefined behavior, which means that it allows you to do absolutely anything at all, up to sending your professor a vulgar and insulting letter that looks like this from you, but in practice it will probably print one of its expected results, there is simply no way to guess which one.)

+1
source

Change your sort cycle to

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

Source: https://habr.com/ru/post/1482781/


All Articles