2

Found some very bizarre behaviour when trying to brainstorm a problem:

Purpose of code: Simple code to find the largest number in an array. I simply store the first index to a variable and compare it to every other index in the list. If another number is larger, that number replaces the number stored in my variable and the process repeats until the end of the list.

#include <stdio.h>

const int SIZE = 8;

int main(void)
{
    int arr[] = {7, 3, 9, 14, 1, 27, 14, 2};
    int largest;

    largest = arr[0];

    for (int i = 1; i <= SIZE; i++)
    {
        if (largest < arr[i])
        {
            largest = arr[i];
        }
    }

    printf("The largest number in the array is %i\n", largest);
}

Weird behaviour: This works, sometimes. Other times I get large numbers that give me the impression I've hit an area of memory I shouldn't have. I could understand if this happened every time but because it only happens every 2nd or 3rd time I compile the code I'm bewildered. The code doesn't change and yet the output does

Console Log:

~/pset3/plurality/ $ ./test
The largest number in the array is 1366797536
~/pset3/plurality/ $ ./test
The largest number in the array is 27
~/pset3/plurality/ $ ./test
The largest number in the array is 27
~/pset3/plurality/ $ ./test
The largest number in the array is 1773422672
~/pset3/plurality/ $ 

My ideas: The loop somehow hits goes past the end of the array and sees that as the largest number. Again the bizarreness of this is that this only happens 50% of the time

Any ideas would be greatly appreciated.

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
user13641095
  • 107
  • 6
  • 2
    Array indices in C start from `0`. And ends at `SIZE-1`. – kaylum Jan 15 '21 at 10:54
  • 2
    You need `< SIZE`, not `<= SIZE` – mousetail Jan 15 '21 at 10:55
  • "*The loop somehow hits goes past the end of the array*" => then you already have your answer, its a fencepost error – costaparas Jan 15 '21 at 10:56
  • Yep, using `< SIZE` fixes the problem. My question remains as to why this error occurred seemingly randomly rather than consistently – user13641095 Jan 15 '21 at 10:57
  • What exact behaviour would you expect instead? Accessing out of bounds memory is Undefined Behaviour in C. [What is undefined behaviour in C](https://stackoverflow.com/questions/19020504/what-is-undefined-behaviour-in-c). – kaylum Jan 15 '21 at 10:58
  • 1
    If you compile with some basic compilation flags, then you can prevent this happening in the first place, consider `-Wall -Werror -Wextra` for `gcc`/`clang`. You will get a clear warning about undefined behavior in such a case. – costaparas Jan 15 '21 at 10:58
  • 1
    Please also add the all-important missing `return 0;` to the end of your `main` function -- `main` returns an `int`. – costaparas Jan 15 '21 at 11:05
  • @costaparas for posterity I usually would. But I recently read that my compiler gives my `main` function a return of 0 regardless if I include it or not on a simple 1 function program like this – user13641095 Jan 15 '21 at 11:07

3 Answers3

1

Your loop is executing one time too many. The loop termination condition i <= SIZE will result in the loop body accessing arr[SIZE], which is outside of the arr array -- remember that C array indices start at 0.

Since the array is stored in the stack frame, your code will be fetching some garbage value from the stack located at the first address beyond the array. This garbage value could be anything, and so could be a large positive value, resulting in what you are seeing.

John Källén
  • 7,551
  • 31
  • 64
1

In C the arrays indices start from 0 to N - 1, with N begin the number of elements of that array, when you do:

for (int i = 1; i <= SIZE; i++)

you are accessing a position out of the allocate memory for that array, therefore you will be reading a random value from memory. Which is considered to be undefined behavior. Hence the reason why:

Again the bizarreness of this is that this only happens 50% of the time

Sometimes the value that you will be reading from the position outside the array boundaries (i.e., will arr[i] with i = SIZE); will be bigger than the values that you have on the array, other times it will not. Hence, the name undefined behavior.

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
0

TLDR: You count i to 8 instead of 7 so you access a value out of bounds of the array. Remove the = sign in the declaration of the for loop.

You are counting from 1...8 in your for loop.

const int SIZE = 8;
… 
for (int i = 1; i <= SIZE; i++)

Your Array has 8 values stored so you can access them with arr[0]arr[7]

If you Access arr[8], which happens in the last Iteration of the for loop since you Count i up to 8 instead of 7 you Access a value out of Bounds, which gives you a kinda random value

radrow
  • 6,419
  • 4
  • 26
  • 53